mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-07-26 12:04:13 -04:00
72d612d986
Query the PlutoSDR hardware for the current RX gain range and use it to configure the GUI gain control dynamically. The AD936x gain limits vary with LO frequency. Previously the GUI used a fixed gain range, allowing users to select values that the hardware would reject after changing bands. The gain slider now refreshes its minimum, maximum, and step size whenever the device center frequency is updated. Also change the gain setting serialization to use a signed integer so negative gain values are preserved for operating modes that support them. Changes include: - Add DevicePlutoSDRBox::getGainRange() to read in_voltage0_hardwaregain_available. - Expose gain range through PlutoSDRInput. - Refresh GUI gain limits when the device frequency changes. - Avoid unnecessary widget updates when limits are unchanged. - Store/restore gain as a signed value. - Add default RX gain limit constants for fallback when the device cannot provide its range. Signed-off-by: Robin Getz <rgetz503@gmail.com>
686 lines
25 KiB
C++
686 lines
25 KiB
C++
///////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
|
// written by Christian Daniel //
|
|
// Copyright (C) 2015-2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
|
// Copyright (C) 2019 Robin Getz <robin.getz@analog.com> //
|
|
// Copyright (C) 2022-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
|
// //
|
|
// 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 <http://www.gnu.org/licenses/>. //
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <stdio.h>
|
|
#include <QDebug>
|
|
#include <QMessageBox>
|
|
#include <QFileDialog>
|
|
|
|
#include "dsp/dspcommands.h"
|
|
#include "gui/glspectrum.h"
|
|
#include "gui/basicdevicesettingsdialog.h"
|
|
#include "gui/dialpopup.h"
|
|
#include "gui/dialogpositioner.h"
|
|
#include "mainspectrum/mainspectrumgui.h"
|
|
#include "device/deviceapi.h"
|
|
#include "device/deviceuiset.h"
|
|
#include "plutosdr/deviceplutosdr.h"
|
|
#include "plutosdrinput.h"
|
|
#include "ui_plutosdrinputgui.h"
|
|
#include "plutosdrinputgui.h"
|
|
|
|
PlutoSDRInputGui::PlutoSDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) :
|
|
DeviceGUI(parent),
|
|
ui(new Ui::PlutoSDRInputGUI),
|
|
m_settings(),
|
|
m_sampleRateMode(true),
|
|
m_forceSettings(true),
|
|
m_sampleSource(NULL),
|
|
m_sampleRate(0),
|
|
m_deviceCenterFrequency(0),
|
|
m_lastEngineState(DeviceAPI::StNotStarted),
|
|
m_doApplySettings(true),
|
|
m_statusCounter(0)
|
|
{
|
|
m_deviceUISet = deviceUISet;
|
|
setAttribute(Qt::WA_DeleteOnClose, true);
|
|
m_sampleSource = (PlutoSDRInput*) m_deviceUISet->m_deviceAPI->getSampleSource();
|
|
|
|
ui->setupUi(getContents());
|
|
sizeToContents();
|
|
getContents()->setStyleSheet("#PlutoSDRInputGUI { background-color: rgb(64, 64, 64); }");
|
|
m_helpURL = "plugins/samplesource/plutosdrinput/readme.md";
|
|
ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
|
updateFrequencyLimits();
|
|
|
|
ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
|
|
ui->sampleRate->setValueRange(8, DevicePlutoSDR::srLowLimitFreq, DevicePlutoSDR::srHighLimitFreq);
|
|
|
|
ui->lpf->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
|
|
|
quint32 minLimit, maxLimit;
|
|
((PlutoSDRInput *) m_sampleSource)->getbbLPRange(minLimit, maxLimit);
|
|
ui->lpf->setValueRange(5, minLimit/1000, maxLimit/1000);
|
|
|
|
refreshGainLimits();
|
|
|
|
ui->lpFIR->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
|
ui->lpFIR->setValueRange(5, 1U, 56000U); // will be dynamically recalculated
|
|
|
|
ui->swDecimLabel->setText(QString::fromUtf8("S\u2193"));
|
|
ui->lpFIRDecimationLabel->setText(QString::fromUtf8("\u2193"));
|
|
|
|
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
|
|
|
|
blockApplySettings(true);
|
|
displaySettings();
|
|
makeUIConnections();
|
|
blockApplySettings(false);
|
|
|
|
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
|
|
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
|
|
m_statusTimer.start(500);
|
|
|
|
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
|
m_sampleSource->setMessageQueueToGUI(&m_inputMessageQueue);
|
|
DialPopup::addPopupsToChildDials(this);
|
|
m_resizer.enableChildMouseTracking();
|
|
}
|
|
|
|
PlutoSDRInputGui::~PlutoSDRInputGui()
|
|
{
|
|
m_statusTimer.stop();
|
|
m_updateTimer.stop();
|
|
delete ui;
|
|
}
|
|
|
|
void PlutoSDRInputGui::destroy()
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
void PlutoSDRInputGui::resetToDefaults()
|
|
{
|
|
m_settings.resetToDefaults();
|
|
displaySettings();
|
|
m_forceSettings = true;
|
|
sendSettings();
|
|
}
|
|
|
|
QByteArray PlutoSDRInputGui::serialize() const
|
|
{
|
|
return m_settings.serialize();
|
|
}
|
|
|
|
bool PlutoSDRInputGui::deserialize(const QByteArray& data)
|
|
{
|
|
if(m_settings.deserialize(data))
|
|
{
|
|
blockApplySettings(true);
|
|
displaySettings();
|
|
blockApplySettings(false);
|
|
m_forceSettings = true;
|
|
sendSettings(true);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
resetToDefaults();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool PlutoSDRInputGui::handleMessage(const Message& message)
|
|
{
|
|
if (PlutoSDRInput::MsgConfigurePlutoSDR::match(message))
|
|
{
|
|
const PlutoSDRInput::MsgConfigurePlutoSDR& cfg = (PlutoSDRInput::MsgConfigurePlutoSDR&) message;
|
|
|
|
if (cfg.getForce()) {
|
|
m_settings = cfg.getSettings();
|
|
} else {
|
|
m_settings.applySettings(cfg.getSettingsKeys(), cfg.getSettings());
|
|
}
|
|
|
|
blockApplySettings(true);
|
|
displaySettings();
|
|
blockApplySettings(false);
|
|
return true;
|
|
}
|
|
else if (PlutoSDRInput::MsgStartStop::match(message))
|
|
{
|
|
PlutoSDRInput::MsgStartStop& notif = (PlutoSDRInput::MsgStartStop&) message;
|
|
blockApplySettings(true);
|
|
ui->startStop->setChecked(notif.getStartStop());
|
|
blockApplySettings(false);
|
|
|
|
return true;
|
|
}
|
|
else if (DevicePlutoSDRShared::MsgCrossReportToBuddy::match(message)) // message from buddy
|
|
{
|
|
DevicePlutoSDRShared::MsgCrossReportToBuddy& conf = (DevicePlutoSDRShared::MsgCrossReportToBuddy&) message;
|
|
m_settings.m_devSampleRate = conf.getDevSampleRate();
|
|
m_settings.m_lpfFIRlog2Decim = conf.getLpfFiRlog2IntDec();
|
|
m_settings.m_lpfFIRBW = conf.getLpfFirbw();
|
|
m_settings.m_LOppmTenths = conf.getLoPPMTenths();
|
|
m_settings.m_lpfFIREnable = conf.isLpfFirEnable();
|
|
blockApplySettings(true);
|
|
displaySettings();
|
|
blockApplySettings(false);
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_startStop_toggled(bool checked)
|
|
{
|
|
if (m_doApplySettings)
|
|
{
|
|
PlutoSDRInput::MsgStartStop *message = PlutoSDRInput::MsgStartStop::create(checked);
|
|
m_sampleSource->getInputMessageQueue()->push(message);
|
|
}
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_centerFrequency_changed(quint64 value)
|
|
{
|
|
m_settings.m_centerFrequency = value * 1000;
|
|
m_settingsKeys.append("centerFrequency");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_loPPM_valueChanged(int value)
|
|
{
|
|
ui->loPPMText->setText(QString("%1").arg(QString::number(value/10.0, 'f', 1)));
|
|
m_settings.m_LOppmTenths = value;
|
|
m_settingsKeys.append("LOppmTenths");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_dcOffset_toggled(bool checked)
|
|
{
|
|
m_settings.m_dcBlock = checked;
|
|
m_settingsKeys.append("dcBlock");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_iqImbalance_toggled(bool checked)
|
|
{
|
|
m_settings.m_iqCorrection = checked;
|
|
m_settingsKeys.append("iqCorrection");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_rfDCOffset_toggled(bool checked)
|
|
{
|
|
m_settings.m_hwRFDCBlock = checked;
|
|
m_settingsKeys.append("hwRFDCBlock");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_bbDCOffset_toggled(bool checked)
|
|
{
|
|
m_settings.m_hwBBDCBlock = checked;
|
|
m_settingsKeys.append("hwBBDCBlock");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_hwIQImbalance_toggled(bool checked)
|
|
{
|
|
m_settings.m_hwIQCorrection = checked;
|
|
m_settingsKeys.append("hwIQCorrection");
|
|
sendSettings();
|
|
}
|
|
|
|
|
|
void PlutoSDRInputGui::on_swDecim_currentIndexChanged(int index)
|
|
{
|
|
m_settings.m_log2Decim = index > 6 ? 6 : index;
|
|
displaySampleRate();
|
|
m_settings.m_devSampleRate = ui->sampleRate->getValueNew();
|
|
|
|
if (!m_sampleRateMode) {
|
|
m_settings.m_devSampleRate <<= m_settings.m_log2Decim;
|
|
}
|
|
|
|
m_settingsKeys.append("log2Decim");
|
|
m_settingsKeys.append("devSampleRate");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_fcPos_currentIndexChanged(int index)
|
|
{
|
|
m_settings.m_fcPos = (PlutoSDRInputSettings::fcPos_t) (index < (int) PlutoSDRInputSettings::FC_POS_END ? index : PlutoSDRInputSettings::FC_POS_CENTER);
|
|
displayFcTooltip();
|
|
m_settingsKeys.append("fcPos");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_sampleRate_changed(quint64 value)
|
|
{
|
|
m_settings.m_devSampleRate = value;
|
|
|
|
if (!m_sampleRateMode) {
|
|
m_settings.m_devSampleRate <<= m_settings.m_log2Decim;
|
|
}
|
|
|
|
displayFcTooltip();
|
|
m_settingsKeys.append("devSampleRate");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_lpf_changed(quint64 value)
|
|
{
|
|
m_settings.m_lpfBW = value * 1000;
|
|
m_settingsKeys.append("lpfBW");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_lpFIREnable_toggled(bool checked)
|
|
{
|
|
m_settings.m_lpfFIREnable = checked;
|
|
ui->lpFIRDecimation->setEnabled(checked);
|
|
ui->lpFIRGain->setEnabled(checked);
|
|
m_settingsKeys.append("lpfFIREnable");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_lpFIR_changed(quint64 value)
|
|
{
|
|
m_settings.m_lpfFIRBW = value * 1000;
|
|
m_settingsKeys.append("lpfFIRBW");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_lpFIRDecimation_currentIndexChanged(int index)
|
|
{
|
|
m_settings.m_lpfFIRlog2Decim = index > 2 ? 2 : index;
|
|
setSampleRateLimits();
|
|
m_settingsKeys.append("lpfFIRlog2Decim");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_lpFIRGain_currentIndexChanged(int index)
|
|
{
|
|
m_settings.m_lpfFIRGain = 6*(index > 3 ? 3 : index) - 12;
|
|
m_settingsKeys.append("lpfFIRGain");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_gainMode_currentIndexChanged(int index)
|
|
{
|
|
m_settings.m_gainMode = (PlutoSDRInputSettings::GainMode) (index < PlutoSDRInputSettings::GAIN_END ? index : 0);
|
|
ui->gain->setEnabled(m_settings.m_gainMode == PlutoSDRInputSettings::GAIN_MANUAL);
|
|
m_settingsKeys.append("gainMode");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_gain_valueChanged(int value)
|
|
{
|
|
ui->gainText->setText(tr("%1").arg(value));
|
|
m_settings.m_gain = value;
|
|
m_settingsKeys.append("gain");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_antenna_currentIndexChanged(int index)
|
|
{
|
|
m_settings.m_antennaPath = (PlutoSDRInputSettings::RFPath) (index < PlutoSDRInputSettings::RFPATH_END ? index : 0);
|
|
m_settingsKeys.append("antennaPath");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_transverter_clicked()
|
|
{
|
|
m_settings.m_transverterMode = ui->transverter->getDeltaFrequencyAcive();
|
|
m_settings.m_transverterDeltaFrequency = ui->transverter->getDeltaFrequency();
|
|
m_settings.m_iqOrder = ui->transverter->getIQOrder();
|
|
qDebug("PlutoSDRInputGui::on_transverter_clicked: %lld Hz %s", m_settings.m_transverterDeltaFrequency, m_settings.m_transverterMode ? "on" : "off");
|
|
updateFrequencyLimits();
|
|
m_settings.m_centerFrequency = ui->centerFrequency->getValueNew()*1000;
|
|
m_settingsKeys.append("transverterMode");
|
|
m_settingsKeys.append("transverterDeltaFrequency");
|
|
m_settingsKeys.append("iqOrder");
|
|
m_settingsKeys.append("centerFrequency");
|
|
sendSettings();
|
|
}
|
|
|
|
void PlutoSDRInputGui::on_sampleRateMode_toggled(bool checked)
|
|
{
|
|
m_sampleRateMode = checked;
|
|
displaySampleRate();
|
|
}
|
|
|
|
void PlutoSDRInputGui::displaySampleRate()
|
|
{
|
|
ui->sampleRate->blockSignals(true);
|
|
displayFcTooltip();
|
|
|
|
if (m_sampleRateMode)
|
|
{
|
|
ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(60,60,60); }");
|
|
ui->sampleRateMode->setText("SR");
|
|
ui->sampleRate->setValueRange(8, DevicePlutoSDR::srLowLimitFreq, DevicePlutoSDR::srHighLimitFreq);
|
|
ui->sampleRate->setValue(m_settings.m_devSampleRate);
|
|
ui->sampleRate->setToolTip("Device to host sample rate (S/s)");
|
|
ui->deviceRateText->setToolTip("Baseband sample rate (S/s)");
|
|
uint32_t basebandSampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim);
|
|
ui->deviceRateText->setText(tr("%1k").arg(QString::number(basebandSampleRate / 1000.0f, 'g', 5)));
|
|
}
|
|
else
|
|
{
|
|
ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(50,50,50); }");
|
|
ui->sampleRateMode->setText("BB");
|
|
ui->sampleRate->setValueRange(8, DevicePlutoSDR::srLowLimitFreq/(1<<m_settings.m_log2Decim), DevicePlutoSDR::srHighLimitFreq/(1<<m_settings.m_log2Decim));
|
|
ui->sampleRate->setValue(m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim));
|
|
ui->sampleRate->setToolTip("Baseband sample rate (S/s)");
|
|
ui->deviceRateText->setToolTip("Device to host sample rate (S/s)");
|
|
ui->deviceRateText->setText(tr("%1k").arg(QString::number(m_settings.m_devSampleRate / 1000.0f, 'g', 5)));
|
|
}
|
|
|
|
ui->sampleRate->blockSignals(false);
|
|
}
|
|
|
|
void PlutoSDRInputGui::refreshGainLimits()
|
|
{
|
|
qint64 minGain, stepGain, maxGain;
|
|
((PlutoSDRInput *) m_sampleSource)->getGainRange(minGain, stepGain, maxGain);
|
|
|
|
// Only update the gui when necessary, avoid unnecessary widget updates
|
|
if (ui->gain->minimum() != minGain ||
|
|
ui->gain->maximum() != maxGain ||
|
|
ui->gain->singleStep() != stepGain)
|
|
{
|
|
ui->gain->setMinimum(minGain);
|
|
ui->gain->setMaximum(maxGain);
|
|
ui->gain->setSingleStep(stepGain);
|
|
}
|
|
}
|
|
|
|
void PlutoSDRInputGui::displayFcTooltip()
|
|
{
|
|
int32_t fShift = DeviceSampleSource::calculateFrequencyShift(
|
|
m_settings.m_log2Decim,
|
|
(DeviceSampleSource::fcPos_t) m_settings.m_fcPos,
|
|
m_settings.m_devSampleRate,
|
|
DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD
|
|
);
|
|
ui->fcPos->setToolTip(tr("Relative position of device center frequency: %1 kHz").arg(QString::number(fShift / 1000.0f, 'g', 5)));
|
|
}
|
|
|
|
void PlutoSDRInputGui::displaySettings()
|
|
{
|
|
setTitle(m_settings.m_title);
|
|
getDeviceUISet()->m_mainSpectrumGUI->setTitle(m_settings.m_title);
|
|
ui->transverter->setDeltaFrequency(m_settings.m_transverterDeltaFrequency);
|
|
ui->transverter->setDeltaFrequencyActive(m_settings.m_transverterMode);
|
|
ui->transverter->setIQOrder(m_settings.m_iqOrder);
|
|
updateFrequencyLimits();
|
|
ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
|
|
displaySampleRate();
|
|
|
|
ui->dcOffset->setChecked(m_settings.m_dcBlock);
|
|
ui->iqImbalance->setChecked(m_settings.m_iqCorrection);
|
|
ui->bbDCOffset->setChecked(m_settings.m_hwBBDCBlock);
|
|
ui->rfDCOffset->setChecked(m_settings.m_hwRFDCBlock);
|
|
ui->hwIQImbalance->setChecked(m_settings.m_hwIQCorrection);
|
|
ui->loPPM->setValue(m_settings.m_LOppmTenths);
|
|
ui->loPPMText->setText(QString("%1").arg(QString::number(m_settings.m_LOppmTenths/10.0, 'f', 1)));
|
|
|
|
ui->swDecim->setCurrentIndex(m_settings.m_log2Decim);
|
|
ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos);
|
|
|
|
ui->lpf->setValue(m_settings.m_lpfBW / 1000);
|
|
|
|
ui->lpFIREnable->setChecked(m_settings.m_lpfFIREnable);
|
|
ui->lpFIR->setValue(m_settings.m_lpfFIRBW / 1000);
|
|
ui->lpFIRDecimation->setCurrentIndex(m_settings.m_lpfFIRlog2Decim);
|
|
ui->lpFIRGain->setCurrentIndex((m_settings.m_lpfFIRGain + 12)/6);
|
|
ui->lpFIRDecimation->setEnabled(m_settings.m_lpfFIREnable);
|
|
ui->lpFIRGain->setEnabled(m_settings.m_lpfFIREnable);
|
|
|
|
ui->gainMode->setCurrentIndex((int) m_settings.m_gainMode);
|
|
ui->gain->setValue(m_settings.m_gain);
|
|
ui->gainText->setText(tr("%1").arg(m_settings.m_gain));
|
|
|
|
ui->antenna->setCurrentIndex((int) m_settings.m_antennaPath);
|
|
|
|
setFIRBWLimits();
|
|
setSampleRateLimits();
|
|
}
|
|
|
|
void PlutoSDRInputGui::sendSettings(bool forceSettings)
|
|
{
|
|
m_forceSettings = forceSettings;
|
|
if(!m_updateTimer.isActive()) { m_updateTimer.start(100); }
|
|
}
|
|
|
|
void PlutoSDRInputGui::updateHardware()
|
|
{
|
|
if (m_doApplySettings)
|
|
{
|
|
qDebug() << "PlutoSDRInputGui::updateHardware";
|
|
PlutoSDRInput::MsgConfigurePlutoSDR* message = PlutoSDRInput::MsgConfigurePlutoSDR::create(m_settings, m_settingsKeys, m_forceSettings);
|
|
m_sampleSource->getInputMessageQueue()->push(message);
|
|
m_forceSettings = false;
|
|
m_settingsKeys.clear();
|
|
m_updateTimer.stop();
|
|
}
|
|
}
|
|
|
|
void PlutoSDRInputGui::blockApplySettings(bool block)
|
|
{
|
|
m_doApplySettings = !block;
|
|
}
|
|
|
|
void PlutoSDRInputGui::updateStatus()
|
|
{
|
|
int state = m_deviceUISet->m_deviceAPI->state();
|
|
|
|
if(m_lastEngineState != state)
|
|
{
|
|
switch(state)
|
|
{
|
|
case DeviceAPI::StNotStarted:
|
|
ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
|
|
break;
|
|
case DeviceAPI::StIdle:
|
|
ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
|
|
break;
|
|
case DeviceAPI::StRunning:
|
|
ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
|
|
break;
|
|
case DeviceAPI::StError:
|
|
ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
|
|
QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
m_lastEngineState = state;
|
|
}
|
|
|
|
if (m_statusCounter % 2 == 0) // 1s
|
|
{
|
|
uint32_t adcRate = ((PlutoSDRInput *) m_sampleSource)->getADCSampleRate();
|
|
|
|
if (adcRate < 100000000) {
|
|
ui->adcRateText->setText(tr("%1k").arg(QString::number(adcRate / 1000.0f, 'g', 5)));
|
|
} else {
|
|
ui->adcRateText->setText(tr("%1M").arg(QString::number(adcRate / 1000000.0f, 'g', 5)));
|
|
}
|
|
}
|
|
|
|
if (m_statusCounter % 4 == 0) // 2s
|
|
{
|
|
std::string rssiStr;
|
|
((PlutoSDRInput *) m_sampleSource)->getRSSI(rssiStr);
|
|
ui->rssiText->setText(tr("-%1").arg(QString::fromStdString(rssiStr)));
|
|
int gaindB;
|
|
((PlutoSDRInput *) m_sampleSource)->getGain(gaindB);
|
|
ui->actualGainText->setText(tr("%1").arg(gaindB));
|
|
}
|
|
|
|
if (m_statusCounter % 10 == 0) // 5s
|
|
{
|
|
if (m_deviceUISet->m_deviceAPI->isBuddyLeader()) {
|
|
((PlutoSDRInput *) m_sampleSource)->fetchTemperature();
|
|
}
|
|
|
|
ui->temperatureText->setText(tr("%1C").arg(QString::number(((PlutoSDRInput *) m_sampleSource)->getTemperature(), 'f', 0)));
|
|
}
|
|
|
|
m_statusCounter++;
|
|
}
|
|
|
|
void PlutoSDRInputGui::setFIRBWLimits()
|
|
{
|
|
float high = DevicePlutoSDR::firBWHighLimitFactor * ((PlutoSDRInput *) m_sampleSource)->getFIRSampleRate();
|
|
float low = DevicePlutoSDR::firBWLowLimitFactor * ((PlutoSDRInput *) m_sampleSource)->getFIRSampleRate();
|
|
ui->lpFIR->setValueRange(5, (int(low)/1000)+1, (int(high)/1000)+1);
|
|
ui->lpFIR->setValue(m_settings.m_lpfFIRBW/1000);
|
|
}
|
|
|
|
void PlutoSDRInputGui::setSampleRateLimits()
|
|
{
|
|
uint32_t low = ui->lpFIREnable->isChecked() ? DevicePlutoSDR::srLowLimitFreq / (1<<ui->lpFIRDecimation->currentIndex()) : DevicePlutoSDR::srLowLimitFreq;
|
|
ui->sampleRate->setValueRange(8, low, DevicePlutoSDR::srHighLimitFreq);
|
|
ui->sampleRate->setValue(m_settings.m_devSampleRate);
|
|
}
|
|
|
|
void PlutoSDRInputGui::updateFrequencyLimits()
|
|
{
|
|
qint64 minLimit, maxLimit;
|
|
// values should be in kHz
|
|
qint64 deltaFrequency = m_settings.m_transverterMode ? m_settings.m_transverterDeltaFrequency/1000 : 0;
|
|
((PlutoSDRInput *) m_sampleSource)->getLORange(minLimit, maxLimit);
|
|
|
|
minLimit = minLimit/1000 + deltaFrequency;
|
|
maxLimit = maxLimit/1000 + deltaFrequency;
|
|
|
|
if (m_settings.m_transverterMode)
|
|
{
|
|
minLimit = minLimit < 0 ? 0 : minLimit > 999999999 ? 999999999 : minLimit;
|
|
maxLimit = maxLimit < 0 ? 0 : maxLimit > 999999999 ? 999999999 : maxLimit;
|
|
ui->centerFrequency->setValueRange(9, minLimit, maxLimit);
|
|
}
|
|
else
|
|
{
|
|
minLimit = minLimit < 0 ? 0 : minLimit > 9999999 ? 9999999 : minLimit;
|
|
maxLimit = maxLimit < 0 ? 0 : maxLimit > 9999999 ? 9999999 : maxLimit;
|
|
ui->centerFrequency->setValueRange(7, minLimit, maxLimit);
|
|
}
|
|
qDebug("PlutoSDRInputGui::updateFrequencyLimits: delta: %lld min: %lld max: %lld", deltaFrequency, minLimit, maxLimit);
|
|
}
|
|
|
|
void PlutoSDRInputGui::handleInputMessages()
|
|
{
|
|
Message* message;
|
|
|
|
while ((message = m_inputMessageQueue.pop()) != 0)
|
|
{
|
|
qDebug("PlutoSDRInputGui::handleInputMessages: message: %s", message->getIdentifier());
|
|
|
|
if (DSPSignalNotification::match(*message))
|
|
{
|
|
DSPSignalNotification* notif = (DSPSignalNotification*) message;
|
|
m_sampleRate = notif->getSampleRate();
|
|
m_deviceCenterFrequency = notif->getCenterFrequency();
|
|
qDebug("PlutoSDRInputGui::handleInputMessages: DSPSignalNotification: SampleRate: %d, CenterFrequency: %llu", notif->getSampleRate(), notif->getCenterFrequency());
|
|
updateSampleRateAndFrequency();
|
|
setFIRBWLimits();
|
|
|
|
delete message;
|
|
}
|
|
else
|
|
{
|
|
if (handleMessage(*message))
|
|
{
|
|
delete message;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void PlutoSDRInputGui::updateSampleRateAndFrequency()
|
|
{
|
|
m_deviceUISet->getSpectrum()->setSampleRate(m_sampleRate);
|
|
m_deviceUISet->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency);
|
|
refreshGainLimits();
|
|
displaySampleRate();
|
|
}
|
|
|
|
void PlutoSDRInputGui::openDeviceSettingsDialog(const QPoint& p)
|
|
{
|
|
if (m_contextMenuType == ContextMenuDeviceSettings)
|
|
{
|
|
BasicDeviceSettingsDialog dialog(this);
|
|
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
|
|
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
|
|
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
|
|
dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
|
|
dialog.setTitle(m_settings.m_title);
|
|
dialog.setDefaultTitle(getDefaultTitle());
|
|
|
|
dialog.move(p);
|
|
new DialogPositioner(&dialog, false);
|
|
dialog.exec();
|
|
|
|
if (dialog.result() == QDialog::Accepted)
|
|
{
|
|
m_settings.m_title = dialog.getTitle();
|
|
setTitle(m_settings.m_title);
|
|
getDeviceUISet()->m_mainSpectrumGUI->setTitle(m_settings.m_title);
|
|
m_settings.m_useReverseAPI = dialog.useReverseAPI();
|
|
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
|
|
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
|
|
m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
|
|
m_settingsKeys.append("useReverseAPI");
|
|
m_settingsKeys.append("reverseAPIAddress");
|
|
m_settingsKeys.append("reverseAPIPort");
|
|
m_settingsKeys.append("reverseAPIDeviceIndex");
|
|
|
|
sendSettings();
|
|
}
|
|
}
|
|
|
|
resetContextMenuType();
|
|
}
|
|
|
|
void PlutoSDRInputGui::makeUIConnections()
|
|
{
|
|
QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &PlutoSDRInputGui::on_startStop_toggled);
|
|
QObject::connect(ui->centerFrequency, &ValueDial::changed, this, &PlutoSDRInputGui::on_centerFrequency_changed);
|
|
QObject::connect(ui->loPPM, &QSlider::valueChanged, this, &PlutoSDRInputGui::on_loPPM_valueChanged);
|
|
QObject::connect(ui->dcOffset, &ButtonSwitch::toggled, this, &PlutoSDRInputGui::on_dcOffset_toggled);
|
|
QObject::connect(ui->rfDCOffset, &ButtonSwitch::toggled, this, &PlutoSDRInputGui::on_rfDCOffset_toggled);
|
|
QObject::connect(ui->bbDCOffset, &ButtonSwitch::toggled, this, &PlutoSDRInputGui::on_bbDCOffset_toggled);
|
|
QObject::connect(ui->hwIQImbalance, &ButtonSwitch::toggled, this, &PlutoSDRInputGui::on_hwIQImbalance_toggled);
|
|
QObject::connect(ui->iqImbalance, &ButtonSwitch::toggled, this, &PlutoSDRInputGui::on_iqImbalance_toggled);
|
|
QObject::connect(ui->swDecim, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlutoSDRInputGui::on_swDecim_currentIndexChanged);
|
|
QObject::connect(ui->fcPos, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlutoSDRInputGui::on_fcPos_currentIndexChanged);
|
|
QObject::connect(ui->sampleRate, &ValueDial::changed, this, &PlutoSDRInputGui::on_sampleRate_changed);
|
|
QObject::connect(ui->lpf, &ValueDial::changed, this, &PlutoSDRInputGui::on_lpf_changed);
|
|
QObject::connect(ui->lpFIREnable, &ButtonSwitch::toggled, this, &PlutoSDRInputGui::on_lpFIREnable_toggled);
|
|
QObject::connect(ui->lpFIR, &ValueDial::changed, this, &PlutoSDRInputGui::on_lpFIR_changed);
|
|
QObject::connect(ui->lpFIRDecimation, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlutoSDRInputGui::on_lpFIRDecimation_currentIndexChanged);
|
|
QObject::connect(ui->lpFIRGain, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlutoSDRInputGui::on_lpFIRGain_currentIndexChanged);
|
|
QObject::connect(ui->gainMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlutoSDRInputGui::on_gainMode_currentIndexChanged);
|
|
QObject::connect(ui->gain, &QDial::valueChanged, this, &PlutoSDRInputGui::on_gain_valueChanged);
|
|
QObject::connect(ui->antenna, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlutoSDRInputGui::on_antenna_currentIndexChanged);
|
|
QObject::connect(ui->transverter, &TransverterButton::clicked, this, &PlutoSDRInputGui::on_transverter_clicked);
|
|
QObject::connect(ui->sampleRateMode, &QToolButton::toggled, this, &PlutoSDRInputGui::on_sampleRateMode_toggled);
|
|
}
|