From 1489dddd0c68deda3e37184e4b6582def83fad4d Mon Sep 17 00:00:00 2001 From: f4exb Date: Sat, 29 Oct 2022 23:56:46 +0200 Subject: [PATCH] BladeRF1 output: Make settings assignments atomic. Part of #1329 --- .../bladerf1output/bladerf1output.cpp | 116 +++++++----------- .../bladerf1output/bladerf1output.h | 13 +- .../bladerf1output/bladerf1outputgui.cpp | 87 ++++++++----- .../bladerf1output/bladerf1outputgui.h | 1 + .../bladerf1output/bladerf1outputsettings.cpp | 90 ++++++++++++++ .../bladerf1output/bladerf1outputsettings.h | 2 + 6 files changed, 201 insertions(+), 108 deletions(-) diff --git a/plugins/samplesink/bladerf1output/bladerf1output.cpp b/plugins/samplesink/bladerf1output/bladerf1output.cpp index 4a86fd63c..780b7f6a9 100644 --- a/plugins/samplesink/bladerf1output/bladerf1output.cpp +++ b/plugins/samplesink/bladerf1output/bladerf1output.cpp @@ -84,8 +84,7 @@ void Bladerf1Output::destroy() bool Bladerf1Output::openDevice() { - if (m_dev != 0) - { + if (m_dev != 0) { closeDevice(); } @@ -142,7 +141,7 @@ bool Bladerf1Output::openDevice() void Bladerf1Output::init() { - applySettings(m_settings, true); + applySettings(m_settings, QList(), true); } bool Bladerf1Output::start() @@ -158,7 +157,7 @@ bool Bladerf1Output::start() m_bladerfThread = new Bladerf1OutputThread(m_dev, &m_sampleSourceFifo); // mutexLocker.unlock(); - applySettings(m_settings, true); + applySettings(m_settings, QList(), true); m_bladerfThread->setLog2Interpolation(m_settings.m_log2Interp); @@ -225,12 +224,12 @@ bool Bladerf1Output::deserialize(const QByteArray& data) success = false; } - MsgConfigureBladerf1* message = MsgConfigureBladerf1::create(m_settings, true); + MsgConfigureBladerf1* message = MsgConfigureBladerf1::create(m_settings, QList(), true); m_inputMessageQueue.push(message); if (m_guiMessageQueue) { - MsgConfigureBladerf1* messageToGUI = MsgConfigureBladerf1::create(m_settings, true); + MsgConfigureBladerf1* messageToGUI = MsgConfigureBladerf1::create(m_settings, QList(), true); m_guiMessageQueue->push(messageToGUI); } @@ -258,12 +257,12 @@ void Bladerf1Output::setCenterFrequency(qint64 centerFrequency) BladeRF1OutputSettings settings = m_settings; settings.m_centerFrequency = centerFrequency; - MsgConfigureBladerf1* message = MsgConfigureBladerf1::create(settings, false); + MsgConfigureBladerf1* message = MsgConfigureBladerf1::create(settings, QList{"centerFrequency"}, false); m_inputMessageQueue.push(message); if (m_guiMessageQueue) { - MsgConfigureBladerf1* messageToGUI = MsgConfigureBladerf1::create(settings, false); + MsgConfigureBladerf1* messageToGUI = MsgConfigureBladerf1::create(settings, QList{"centerFrequency"}, false); m_guiMessageQueue->push(messageToGUI); } } @@ -275,8 +274,7 @@ bool Bladerf1Output::handleMessage(const Message& message) MsgConfigureBladerf1& conf = (MsgConfigureBladerf1&) message; qDebug() << "BladerfOutput::handleMessage: MsgConfigureBladerf"; - if (!applySettings(conf.getSettings(), conf.getForce())) - { + if (!applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce())) { qDebug("BladeRF config error"); } @@ -289,8 +287,7 @@ bool Bladerf1Output::handleMessage(const Message& message) if (cmd.getStartStop()) { - if (m_deviceAPI->initDeviceEngine()) - { + if (m_deviceAPI->initDeviceEngine()) { m_deviceAPI->startDeviceEngine(); } } @@ -311,28 +308,16 @@ bool Bladerf1Output::handleMessage(const Message& message) } } -bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, bool force) +bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, const QList& settingsKeys, bool force) { + qDebug() << "BladerfOutput::applySettings: force:" << force << settings.getDebugString(settingsKeys, force); bool forwardChange = false; bool suspendOwnThread = false; bool threadWasRunning = false; - QList reverseAPIKeys; // QMutexLocker mutexLocker(&m_mutex); - qDebug() << "BladerfOutput::applySettings: m_dev: " << m_dev; - - if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) { - reverseAPIKeys.append("centerFrequency"); - } - if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force) { - reverseAPIKeys.append("devSampleRate"); - } - if ((m_settings.m_log2Interp != settings.m_log2Interp) || force) { - reverseAPIKeys.append("log2Interp"); - } - - if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || - (m_settings.m_log2Interp != settings.m_log2Interp) || force) + if (settingsKeys.contains("devSampleRate") || + settingsKeys.contains("log2Interp") || force) { suspendOwnThread = true; } @@ -349,7 +334,8 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, bool } } - if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || (m_settings.m_log2Interp != settings.m_log2Interp) || force) + if (settingsKeys.contains("devSampleRate") || + settingsKeys.contains("log2Interp") || force) { #if defined(_MSC_VER) unsigned int fifoRate = (unsigned int) settings.m_devSampleRate / (1<startWork(); } - if (settings.m_useReverseAPI) + if (settingsKeys.contains("useReverseAPI")) { - bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || - (m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) || - (m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) || - (m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex); - webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force); + bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) || + settingsKeys.contains("reverseAPIAddress") || + settingsKeys.contains("reverseAPIPort") || + settingsKeys.contains("reverseAPIDeviceIndex"); + webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force); } - m_settings = settings; + if (force) { + m_settings = settings; + } else { + m_settings.applySettings(settingsKeys, settings); + } if (forwardChange) { @@ -544,11 +521,6 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, bool m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); } - qDebug() << "BladerfOutput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz" - << " device sample rate: " << m_settings.m_devSampleRate << "S/s" - << " baseband sample rate: " << m_settings.m_devSampleRate/(1<push(msgToGUI); } @@ -684,7 +656,7 @@ int Bladerf1Output::webapiRun( return 200; } -void Bladerf1Output::webapiReverseSendSettings(QList& deviceSettingsKeys, const BladeRF1OutputSettings& settings, bool force) +void Bladerf1Output::webapiReverseSendSettings(const QList& deviceSettingsKeys, const BladeRF1OutputSettings& settings, bool force) { SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings(); swgDeviceSettings->setDirection(1); // single Tx diff --git a/plugins/samplesink/bladerf1output/bladerf1output.h b/plugins/samplesink/bladerf1output/bladerf1output.h index cf4d7c8fc..09af531a4 100644 --- a/plugins/samplesink/bladerf1output/bladerf1output.h +++ b/plugins/samplesink/bladerf1output/bladerf1output.h @@ -40,20 +40,23 @@ public: public: const BladeRF1OutputSettings& getSettings() const { return m_settings; } + const QList& getSettingsKeys() const { return m_settingsKeys; } bool getForce() const { return m_force; } - static MsgConfigureBladerf1* create(const BladeRF1OutputSettings& settings, bool force) + static MsgConfigureBladerf1* create(const BladeRF1OutputSettings& settings, const QList& settingsKeys, bool force) { - return new MsgConfigureBladerf1(settings, force); + return new MsgConfigureBladerf1(settings, settingsKeys, force); } private: BladeRF1OutputSettings m_settings; + QList m_settingsKeys; bool m_force; - MsgConfigureBladerf1(const BladeRF1OutputSettings& settings, bool force) : + MsgConfigureBladerf1(const BladeRF1OutputSettings& settings, const QList& settingsKeys, bool force) : Message(), m_settings(settings), + m_settingsKeys(settingsKeys), m_force(force) { } }; @@ -156,8 +159,8 @@ private: bool openDevice(); void closeDevice(); - bool applySettings(const BladeRF1OutputSettings& settings, bool force); - void webapiReverseSendSettings(QList& deviceSettingsKeys, const BladeRF1OutputSettings& settings, bool force); + bool applySettings(const BladeRF1OutputSettings& settings, const QList& settingsKeys, bool force); + void webapiReverseSendSettings(const QList& deviceSettingsKeys, const BladeRF1OutputSettings& settings, bool force); void webapiReverseSendStartStop(bool start); private slots: diff --git a/plugins/samplesink/bladerf1output/bladerf1outputgui.cpp b/plugins/samplesink/bladerf1output/bladerf1outputgui.cpp index 7fdc6a030..8e18af396 100644 --- a/plugins/samplesink/bladerf1output/bladerf1outputgui.cpp +++ b/plugins/samplesink/bladerf1output/bladerf1outputgui.cpp @@ -90,6 +90,7 @@ void Bladerf1OutputGui::resetToDefaults() { m_settings.resetToDefaults(); displaySettings(); + m_forceSettings = true; sendSettings(); } @@ -100,12 +101,15 @@ QByteArray Bladerf1OutputGui::serialize() const bool Bladerf1OutputGui::deserialize(const QByteArray& data) { - if(m_settings.deserialize(data)) { + if (m_settings.deserialize(data)) + { displaySettings(); m_forceSettings = true; sendSettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } @@ -122,7 +126,13 @@ bool Bladerf1OutputGui::handleMessage(const Message& message) if (Bladerf1Output::MsgConfigureBladerf1::match(message)) { const Bladerf1Output::MsgConfigureBladerf1& cfg = (Bladerf1Output::MsgConfigureBladerf1&) message; - m_settings = cfg.getSettings(); + + if (cfg.getForce()) { + m_settings = cfg.getSettings(); + } else { + m_settings.applySettings(cfg.getSettingsKeys(), cfg.getSettings()); + } + blockApplySettings(true); displaySettings(); blockApplySettings(false); @@ -167,8 +177,7 @@ void Bladerf1OutputGui::handleInputMessages() } else { - if (handleMessage(*message)) - { + if (handleMessage(*message)) { delete message; } } @@ -232,13 +241,15 @@ void Bladerf1OutputGui::displaySettings() void Bladerf1OutputGui::sendSettings() { - if(!m_updateTimer.isActive()) + if (!m_updateTimer.isActive()) { m_updateTimer.start(100); + } } void Bladerf1OutputGui::on_centerFrequency_changed(quint64 value) { m_settings.m_centerFrequency = value * 1000; + m_settingsKeys.append("centerFrequency"); sendSettings(); } @@ -250,6 +261,7 @@ void Bladerf1OutputGui::on_sampleRate_changed(quint64 value) m_settings.m_devSampleRate = value * (1 << m_settings.m_log2Interp); } + m_settingsKeys.append("devSampleRate"); sendSettings(); } @@ -257,6 +269,7 @@ void Bladerf1OutputGui::on_bandwidth_currentIndexChanged(int index) { int newbw = BladerfBandwidths::getBandwidth(index); m_settings.m_bandwidth = newbw * 1000; + m_settingsKeys.append("bandwidth"); sendSettings(); } @@ -267,6 +280,7 @@ void Bladerf1OutputGui::on_interp_currentIndexChanged(int index) } m_settings.m_log2Interp = index; + m_settingsKeys.append("log2Interp"); displaySampleRate(); if (m_sampleRateMode) { @@ -275,83 +289,100 @@ void Bladerf1OutputGui::on_interp_currentIndexChanged(int index) m_settings.m_devSampleRate = ui->sampleRate->getValueNew() * (1 << m_settings.m_log2Interp); } + m_settingsKeys.append("devSampleRate"); sendSettings(); } void Bladerf1OutputGui::on_vga1_valueChanged(int value) { - if ((value < BLADERF_TXVGA1_GAIN_MIN) || (value > BLADERF_TXVGA1_GAIN_MAX)) + if ((value < BLADERF_TXVGA1_GAIN_MIN) || (value > BLADERF_TXVGA1_GAIN_MAX)) { return; + } ui->vga1Text->setText(tr("%1dB").arg(value)); m_settings.m_vga1 = value; + m_settingsKeys.append("vga1"); sendSettings(); } void Bladerf1OutputGui::on_vga2_valueChanged(int value) { - if ((value < BLADERF_TXVGA2_GAIN_MIN) || (value > BLADERF_TXVGA2_GAIN_MAX)) + if ((value < BLADERF_TXVGA2_GAIN_MIN) || (value > BLADERF_TXVGA2_GAIN_MAX)) { return; + } ui->vga2Text->setText(tr("%1dB").arg(value)); m_settings.m_vga2 = value; + m_settingsKeys.append("vga2"); sendSettings(); } void Bladerf1OutputGui::on_xb200_currentIndexChanged(int index) { + m_settingsKeys.append("xb200"); + if (index == 1) // bypass { m_settings.m_xb200 = true; m_settings.m_xb200Path = BLADERF_XB200_BYPASS; + m_settingsKeys.append("xb200Path"); } else if (index == 2) // Auto 1dB { m_settings.m_xb200 = true; m_settings.m_xb200Path = BLADERF_XB200_MIX; m_settings.m_xb200Filter = BLADERF_XB200_AUTO_1DB; + m_settingsKeys.append("xb200Path"); + m_settingsKeys.append("m_xb200Filter"); } else if (index == 3) // Auto 3dB { m_settings.m_xb200 = true; m_settings.m_xb200Path = BLADERF_XB200_MIX; m_settings.m_xb200Filter = BLADERF_XB200_AUTO_3DB; + m_settingsKeys.append("xb200Path"); + m_settingsKeys.append("m_xb200Filter"); } else if (index == 4) // Custom { m_settings.m_xb200 = true; m_settings.m_xb200Path = BLADERF_XB200_MIX; m_settings.m_xb200Filter = BLADERF_XB200_CUSTOM; + m_settingsKeys.append("xb200Path"); + m_settingsKeys.append("m_xb200Filter"); } else if (index == 5) // 50 MHz { m_settings.m_xb200 = true; m_settings.m_xb200Path = BLADERF_XB200_MIX; m_settings.m_xb200Filter = BLADERF_XB200_50M; + m_settingsKeys.append("xb200Path"); + m_settingsKeys.append("m_xb200Filter"); } else if (index == 6) // 144 MHz { m_settings.m_xb200 = true; m_settings.m_xb200Path = BLADERF_XB200_MIX; m_settings.m_xb200Filter = BLADERF_XB200_144M; + m_settingsKeys.append("xb200Path"); + m_settingsKeys.append("m_xb200Filter"); } else if (index == 7) // 222 MHz { m_settings.m_xb200 = true; m_settings.m_xb200Path = BLADERF_XB200_MIX; m_settings.m_xb200Filter = BLADERF_XB200_222M; + m_settingsKeys.append("xb200Path"); + m_settingsKeys.append("m_xb200Filter"); } else // no xb200 { m_settings.m_xb200 = false; } - if (m_settings.m_xb200) - { + if (m_settings.m_xb200) { ui->centerFrequency->setValueRange(7, BLADERF_FREQUENCY_MIN_XB200/1000, BLADERF_FREQUENCY_MAX/1000); - } - else - { + } else { ui->centerFrequency->setValueRange(7, BLADERF_FREQUENCY_MIN/1000, BLADERF_FREQUENCY_MAX/1000); } @@ -376,9 +407,10 @@ void Bladerf1OutputGui::on_sampleRateMode_toggled(bool checked) void Bladerf1OutputGui::updateHardware() { qDebug() << "BladerfGui::updateHardware"; - Bladerf1Output::MsgConfigureBladerf1* message = Bladerf1Output::MsgConfigureBladerf1::create( m_settings, m_forceSettings); + Bladerf1Output::MsgConfigureBladerf1* message = Bladerf1Output::MsgConfigureBladerf1::create( m_settings, m_settingsKeys, m_forceSettings); m_deviceSampleSink->getInputMessageQueue()->push(message); m_forceSettings = false; + m_settingsKeys.clear(); m_updateTimer.stop(); } @@ -421,28 +453,17 @@ unsigned int Bladerf1OutputGui::getXb200Index(bool xb_200, bladerf_xb200_path xb } else { - if (xb200Filter == BLADERF_XB200_AUTO_1DB) - { + if (xb200Filter == BLADERF_XB200_AUTO_1DB) { return 2; - } - else if (xb200Filter == BLADERF_XB200_AUTO_3DB) - { + } else if (xb200Filter == BLADERF_XB200_AUTO_3DB) { return 3; - } - else if (xb200Filter == BLADERF_XB200_CUSTOM) - { + } else if (xb200Filter == BLADERF_XB200_CUSTOM) { return 4; - } - else if (xb200Filter == BLADERF_XB200_50M) - { + } else if (xb200Filter == BLADERF_XB200_50M) { return 5; - } - else if (xb200Filter == BLADERF_XB200_144M) - { + } else if (xb200Filter == BLADERF_XB200_144M) { return 6; - } - else // xb200Filter == BLADERF_XB200_222M - { + } else { // xb200Filter == BLADERF_XB200_222M return 7; } } @@ -470,6 +491,10 @@ void Bladerf1OutputGui::openDeviceSettingsDialog(const QPoint& p) 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(); } diff --git a/plugins/samplesink/bladerf1output/bladerf1outputgui.h b/plugins/samplesink/bladerf1output/bladerf1outputgui.h index b7689f3f3..423f8102f 100644 --- a/plugins/samplesink/bladerf1output/bladerf1outputgui.h +++ b/plugins/samplesink/bladerf1output/bladerf1outputgui.h @@ -55,6 +55,7 @@ private: bool m_doApplySettings; bool m_forceSettings; BladeRF1OutputSettings m_settings; + QList m_settingsKeys; bool m_sampleRateMode; //!< true: device, false: base band sample rate update mode QTimer m_updateTimer; QTimer m_statusTimer; diff --git a/plugins/samplesink/bladerf1output/bladerf1outputsettings.cpp b/plugins/samplesink/bladerf1output/bladerf1outputsettings.cpp index 42e33f262..2027b0c2d 100644 --- a/plugins/samplesink/bladerf1output/bladerf1outputsettings.cpp +++ b/plugins/samplesink/bladerf1output/bladerf1outputsettings.cpp @@ -109,3 +109,93 @@ bool BladeRF1OutputSettings::deserialize(const QByteArray& data) return false; } } + +void BladeRF1OutputSettings::applySettings(const QStringList& settingsKeys, const BladeRF1OutputSettings& settings) +{ + if (settingsKeys.contains("centerFrequency")) { + m_centerFrequency = settings.m_centerFrequency; + } + if (settingsKeys.contains("devSampleRate")) { + m_devSampleRate = settings.m_devSampleRate; + } + if (settingsKeys.contains("vga1")) { + m_vga1 = settings.m_vga1; + } + if (settingsKeys.contains("vga2")) { + m_vga2 = settings.m_vga2; + } + if (settingsKeys.contains("bandwidth")) { + m_bandwidth = settings.m_bandwidth; + } + if (settingsKeys.contains("log2Interp")) { + m_log2Interp = settings.m_log2Interp; + } + if (settingsKeys.contains("xb200")) { + m_xb200 = settings.m_xb200; + } + if (settingsKeys.contains("xb200Path")) { + m_xb200Path = settings.m_xb200Path; + } + if (settingsKeys.contains("xb200Filter")) { + m_xb200Filter = settings.m_xb200Filter; + } + if (settingsKeys.contains("useReverseAPI")) { + m_useReverseAPI = settings.m_useReverseAPI; + } + if (settingsKeys.contains("reverseAPIAddress")) { + m_reverseAPIAddress = settings.m_reverseAPIAddress; + } + if (settingsKeys.contains("reverseAPIPort")) { + m_reverseAPIPort = settings.m_reverseAPIPort; + } + if (settingsKeys.contains("reverseAPIDeviceIndex")) { + m_reverseAPIDeviceIndex = settings.m_reverseAPIDeviceIndex; + } +} + +QString BladeRF1OutputSettings::getDebugString(const QStringList& settingsKeys, bool force) const +{ + std::ostringstream ostr; + + if (settingsKeys.contains("centerFrequency") || force) { + ostr << " m_centerFrequency: " << m_centerFrequency; + } + if (settingsKeys.contains("devSampleRate") || force) { + ostr << " m_devSampleRate: " << m_devSampleRate; + } + if (settingsKeys.contains("vga1") || force) { + ostr << " m_vga1: " << m_vga1; + } + if (settingsKeys.contains("vga2") || force) { + ostr << " m_vga2: " << m_vga2; + } + if (settingsKeys.contains("bandwidth") || force) { + ostr << " m_bandwidth: " << m_bandwidth; + } + if (settingsKeys.contains("log2Interp") || force) { + ostr << " m_log2Interp: " << m_log2Interp; + } + if (settingsKeys.contains("xb200") || force) { + ostr << " m_xb200: " << m_xb200; + } + if (settingsKeys.contains("xb200Path") || force) { + ostr << " m_xb200Path: " << m_xb200Path; + } + if (settingsKeys.contains("xb200Filter") || force) { + ostr << " m_xb200Filter: " << m_xb200Filter; + } + if (settingsKeys.contains("useReverseAPI") || force) { + ostr << " m_useReverseAPI: " << m_useReverseAPI; + } + if (settingsKeys.contains("reverseAPIAddress") || force) { + ostr << " m_reverseAPIAddress: " << m_reverseAPIAddress.toStdString(); + } + if (settingsKeys.contains("reverseAPIPort") || force) { + ostr << " m_reverseAPIPort: " << m_reverseAPIPort; + } + if (settingsKeys.contains("reverseAPIDeviceIndex") || force) { + ostr << " m_reverseAPIDeviceIndex: " << m_reverseAPIDeviceIndex; + } + + return QString(ostr.str().c_str()); +} diff --git a/plugins/samplesink/bladerf1output/bladerf1outputsettings.h b/plugins/samplesink/bladerf1output/bladerf1outputsettings.h index 71d15376c..2fd9acd98 100644 --- a/plugins/samplesink/bladerf1output/bladerf1outputsettings.h +++ b/plugins/samplesink/bladerf1output/bladerf1outputsettings.h @@ -42,6 +42,8 @@ struct BladeRF1OutputSettings { void resetToDefaults(); QByteArray serialize() const; bool deserialize(const QByteArray& data); + void applySettings(const QStringList& settingsKeys, const BladeRF1OutputSettings& settings); + QString getDebugString(const QStringList& settingsKeys, bool force=false) const; }; #endif /* _BLADERF_BLADERFOUTPUTSETTINGS_H_ */