From a0478d0f73bc591a31634cad438394282b9ba614 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 14 Jan 2019 09:25:08 +0100 Subject: [PATCH] AirspyHF: implemented local DC and IQ imbalance corrections --- plugins/samplesource/airspyhf/airspyhfgui.cpp | 14 ++++++ plugins/samplesource/airspyhf/airspyhfgui.h | 2 + plugins/samplesource/airspyhf/airspyhfgui.ui | 48 ++++++++++++++++++- .../samplesource/airspyhf/airspyhfinput.cpp | 32 ++++++++++++- .../airspyhf/airspyhfsettings.cpp | 6 +++ .../samplesource/airspyhf/airspyhfsettings.h | 12 +++-- sdrbase/resources/webapi/doc/html2/index.html | 8 +++- .../webapi/doc/swagger/include/AirspyHF.yaml | 4 ++ .../api/swagger/include/AirspyHF.yaml | 4 ++ swagger/sdrangel/code/html2/index.html | 8 +++- .../code/qt5/client/SWGAirspyHFSettings.cpp | 42 ++++++++++++++++ .../code/qt5/client/SWGAirspyHFSettings.h | 12 +++++ 12 files changed, 182 insertions(+), 10 deletions(-) diff --git a/plugins/samplesource/airspyhf/airspyhfgui.cpp b/plugins/samplesource/airspyhf/airspyhfgui.cpp index a86fcba50..c8cbe63d8 100644 --- a/plugins/samplesource/airspyhf/airspyhfgui.cpp +++ b/plugins/samplesource/airspyhf/airspyhfgui.cpp @@ -230,6 +230,8 @@ void AirspyHFGui::displaySettings() ui->dsp->setChecked(m_settings.m_useDSP); ui->lna->setChecked(m_settings.m_useLNA); ui->att->setCurrentIndex(m_settings.m_attenuatorSteps); + ui->dcOffset->setChecked(m_settings.m_dcBlock); + ui->iqImbalance->setChecked(m_settings.m_iqCorrection); displayAGC(); blockApplySettings(false); } @@ -402,6 +404,18 @@ void AirspyHFGui::on_att_currentIndexChanged(int index) } } +void AirspyHFGui::on_dcOffset_toggled(bool checked) +{ + m_settings.m_dcBlock = checked; + sendSettings(); +} + +void AirspyHFGui::on_iqImbalance_toggled(bool checked) +{ + m_settings.m_iqCorrection = checked; + sendSettings(); +} + void AirspyHFGui::updateHardware() { qDebug() << "AirspyHFGui::updateHardware"; diff --git a/plugins/samplesource/airspyhf/airspyhfgui.h b/plugins/samplesource/airspyhf/airspyhfgui.h index ef30271f1..436984411 100644 --- a/plugins/samplesource/airspyhf/airspyhfgui.h +++ b/plugins/samplesource/airspyhf/airspyhfgui.h @@ -81,6 +81,8 @@ private slots: void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); void on_resetLOppm_clicked(); + void on_dcOffset_toggled(bool checked); + void on_iqImbalance_toggled(bool checked); void on_sampleRate_currentIndexChanged(int index); void on_decim_currentIndexChanged(int index); void on_startStop_toggled(bool checked); diff --git a/plugins/samplesource/airspyhf/airspyhfgui.ui b/plugins/samplesource/airspyhf/airspyhfgui.ui index 1cd52497a..368ca00ae 100644 --- a/plugins/samplesource/airspyhf/airspyhfgui.ui +++ b/plugins/samplesource/airspyhf/airspyhfgui.ui @@ -6,7 +6,7 @@ 0 0 - 324 + 320 160 @@ -235,6 +235,26 @@ + + + + DC component block (internal DSP) + + + DC + + + + + + + IQ imbalance correction (internal DSP) + + + IQ + + + @@ -420,12 +440,21 @@ + + + 55 + 0 + + 55 16777215 + + AGC mode and threshold (HF only) + Off @@ -445,6 +474,9 @@ + + LNA on/off (HF only) + LNA @@ -459,12 +491,21 @@ + + + 42 + 0 + + - 40 + 42 16777215 + + Attenuator (AGC off and HF only) + 0 @@ -534,6 +575,9 @@ + + Toggle libairspyhf DSP on/off + DSP diff --git a/plugins/samplesource/airspyhf/airspyhfinput.cpp b/plugins/samplesource/airspyhf/airspyhfinput.cpp index 061815cf3..09e34e9cb 100644 --- a/plugins/samplesource/airspyhf/airspyhfinput.cpp +++ b/plugins/samplesource/airspyhf/airspyhfinput.cpp @@ -389,12 +389,15 @@ bool AirspyHFInput::applySettings(const AirspyHFSettings& settings, bool force) << " m_fileRecordName: " << settings.m_fileRecordName << " m_useDSP: " << settings.m_useDSP << " m_useAGC: " << settings.m_useAGC + << " m_agcHigh: " << settings.m_agcHigh << " m_useLNA: " << settings.m_useLNA << " m_attenuatorSteps: " << settings.m_attenuatorSteps << " m_useReverseAPI: " << settings.m_useReverseAPI << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress << " m_reverseAPIPort: " << settings.m_reverseAPIPort - << " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex; + << " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex + << " m_dcBlock: " << settings.m_dcBlock + << " m_iqCorrection: " << settings.m_iqCorrection; QMutexLocker mutexLocker(&m_mutex); @@ -404,6 +407,19 @@ bool AirspyHFInput::applySettings(const AirspyHFSettings& settings, bool force) int sampleRateIndex = settings.m_devSampleRateIndex; + if ((m_settings.m_dcBlock != settings.m_dcBlock) || force) { + reverseAPIKeys.append("dcBlock"); + } + if ((m_settings.m_iqCorrection != settings.m_iqCorrection) || force) { + reverseAPIKeys.append("iqCorrection"); + } + + if ((m_settings.m_dcBlock != settings.m_dcBlock) || + (m_settings.m_iqCorrection != settings.m_iqCorrection) || force) + { + m_deviceAPI->configureCorrections(settings.m_dcBlock, settings.m_iqCorrection); + } + if ((m_settings.m_bandIndex != settings.m_bandIndex) || force) { reverseAPIKeys.append("bandIndex"); } @@ -695,6 +711,12 @@ int AirspyHFInput::webapiSettingsPutPatch( if (deviceSettingsKeys.contains("attenuatorSteps")) { settings.m_attenuatorSteps = response.getAirspyHfSettings()->getAttenuatorSteps(); } + if (deviceSettingsKeys.contains("dcBlock")) { + settings.m_dcBlock = response.getAirspyHfSettings()->getDcBlock() != 0; + } + if (deviceSettingsKeys.contains("iqCorrection")) { + settings.m_iqCorrection = response.getAirspyHfSettings()->getIqCorrection() != 0; + } MsgConfigureAirspyHF *msg = MsgConfigureAirspyHF::create(settings, force); m_inputMessageQueue.push(msg); @@ -740,6 +762,8 @@ void AirspyHFInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& r response.getAirspyHfSettings()->setUseLna(settings.m_useLNA ? 1 : 0); response.getAirspyHfSettings()->setAgcHigh(settings.m_agcHigh ? 1 : 0); response.getAirspyHfSettings()->setAttenuatorSteps(settings.m_attenuatorSteps); + response.getAirspyHfSettings()->setDcBlock(settings.m_dcBlock ? 1 : 0); + response.getAirspyHfSettings()->setIqCorrection(settings.m_iqCorrection ? 1 : 0); } void AirspyHFInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) @@ -841,6 +865,12 @@ void AirspyHFInput::webapiReverseSendSettings(QList& deviceSettingsKeys if (deviceSettingsKeys.contains("attenuatorSteps")) { swgAirspyHFSettings->setAttenuatorSteps(settings.m_attenuatorSteps); } + if (deviceSettingsKeys.contains("dcBlock") || force) { + swgAirspyHFSettings->setDcBlock(settings.m_dcBlock ? 1 : 0); + } + if (deviceSettingsKeys.contains("iqCorrection") || force) { + swgAirspyHFSettings->setIqCorrection(settings.m_iqCorrection ? 1 : 0); + } QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") .arg(settings.m_reverseAPIAddress) diff --git a/plugins/samplesource/airspyhf/airspyhfsettings.cpp b/plugins/samplesource/airspyhf/airspyhfsettings.cpp index 4839db191..27c950d46 100644 --- a/plugins/samplesource/airspyhf/airspyhfsettings.cpp +++ b/plugins/samplesource/airspyhf/airspyhfsettings.cpp @@ -43,6 +43,8 @@ void AirspyHFSettings::resetToDefaults() m_agcHigh = false; m_useLNA = false; m_attenuatorSteps = 0; + m_dcBlock = false; + m_iqCorrection = false; } QByteArray AirspyHFSettings::serialize() const @@ -64,6 +66,8 @@ QByteArray AirspyHFSettings::serialize() const s.writeBool(16, m_agcHigh); s.writeBool(17, m_useLNA); s.writeU32(18, m_attenuatorSteps); + s.writeBool(19, m_dcBlock); + s.writeBool(20, m_iqCorrection); return s.final(); } @@ -108,6 +112,8 @@ bool AirspyHFSettings::deserialize(const QByteArray& data) d.readBool(16, &m_agcHigh, false); d.readBool(17, &m_useLNA, false); d.readU32(18, &m_attenuatorSteps, 0); + d.readBool(19, &m_dcBlock, false); + d.readBool(20, &m_iqCorrection, false); return true; } diff --git a/plugins/samplesource/airspyhf/airspyhfsettings.h b/plugins/samplesource/airspyhf/airspyhfsettings.h index bf4582e7e..390c9f046 100644 --- a/plugins/samplesource/airspyhf/airspyhfsettings.h +++ b/plugins/samplesource/airspyhf/airspyhfsettings.h @@ -29,15 +29,17 @@ struct AirspyHFSettings qint64 m_transverterDeltaFrequency; quint32 m_bandIndex; QString m_fileRecordName; - bool m_useReverseAPI; + bool m_useReverseAPI; QString m_reverseAPIAddress; uint16_t m_reverseAPIPort; uint16_t m_reverseAPIDeviceIndex; - bool m_useDSP; - bool m_useAGC; - bool m_agcHigh; - bool m_useLNA; + bool m_useDSP; + bool m_useAGC; + bool m_agcHigh; + bool m_useLNA; quint32 m_attenuatorSteps; + bool m_dcBlock; + bool m_iqCorrection; AirspyHFSettings(); void resetToDefaults(); diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index 29a5573c4..9b6ea1a93 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -1039,6 +1039,12 @@ margin-bottom: 20px; "attenuatorSteps" : { "type" : "integer", "description" : "Attenuator in number of 6 dB steps" + }, + "dcBlock" : { + "type" : "integer" + }, + "iqCorrection" : { + "type" : "integer" } }, "description" : "AirspyHF" @@ -24367,7 +24373,7 @@ except ApiException as e:
- Generated 2019-01-14T01:23:06.065+01:00 + Generated 2019-01-14T08:33:10.665+01:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/AirspyHF.yaml b/sdrbase/resources/webapi/doc/swagger/include/AirspyHF.yaml index 9c452224c..59649bcfd 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/AirspyHF.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/AirspyHF.yaml @@ -43,6 +43,10 @@ AirspyHFSettings: attenuatorSteps: description: Attenuator in number of 6 dB steps type: integer + dcBlock: + type: integer + iqCorrection: + type: integer AirspyHFReport: description: AirspyHF diff --git a/swagger/sdrangel/api/swagger/include/AirspyHF.yaml b/swagger/sdrangel/api/swagger/include/AirspyHF.yaml index 6eaf34bdb..c6da49ac9 100644 --- a/swagger/sdrangel/api/swagger/include/AirspyHF.yaml +++ b/swagger/sdrangel/api/swagger/include/AirspyHF.yaml @@ -43,6 +43,10 @@ AirspyHFSettings: attenuatorSteps: description: Attenuator in number of 6 dB steps type: integer + dcBlock: + type: integer + iqCorrection: + type: integer AirspyHFReport: description: AirspyHF diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index 29a5573c4..9b6ea1a93 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -1039,6 +1039,12 @@ margin-bottom: 20px; "attenuatorSteps" : { "type" : "integer", "description" : "Attenuator in number of 6 dB steps" + }, + "dcBlock" : { + "type" : "integer" + }, + "iqCorrection" : { + "type" : "integer" } }, "description" : "AirspyHF" @@ -24367,7 +24373,7 @@ except ApiException as e:
- Generated 2019-01-14T01:23:06.065+01:00 + Generated 2019-01-14T08:33:10.665+01:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGAirspyHFSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGAirspyHFSettings.cpp index 39f600f02..c6715c5c2 100644 --- a/swagger/sdrangel/code/qt5/client/SWGAirspyHFSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGAirspyHFSettings.cpp @@ -62,6 +62,10 @@ SWGAirspyHFSettings::SWGAirspyHFSettings() { m_use_lna_isSet = false; attenuator_steps = 0; m_attenuator_steps_isSet = false; + dc_block = 0; + m_dc_block_isSet = false; + iq_correction = 0; + m_iq_correction_isSet = false; } SWGAirspyHFSettings::~SWGAirspyHFSettings() { @@ -104,6 +108,10 @@ SWGAirspyHFSettings::init() { m_use_lna_isSet = false; attenuator_steps = 0; m_attenuator_steps_isSet = false; + dc_block = 0; + m_dc_block_isSet = false; + iq_correction = 0; + m_iq_correction_isSet = false; } void @@ -129,6 +137,8 @@ SWGAirspyHFSettings::cleanup() { + + } SWGAirspyHFSettings* @@ -176,6 +186,10 @@ SWGAirspyHFSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&attenuator_steps, pJson["attenuatorSteps"], "qint32", ""); + ::SWGSDRangel::setValue(&dc_block, pJson["dcBlock"], "qint32", ""); + + ::SWGSDRangel::setValue(&iq_correction, pJson["iqCorrection"], "qint32", ""); + } QString @@ -243,6 +257,12 @@ SWGAirspyHFSettings::asJsonObject() { if(m_attenuator_steps_isSet){ obj->insert("attenuatorSteps", QJsonValue(attenuator_steps)); } + if(m_dc_block_isSet){ + obj->insert("dcBlock", QJsonValue(dc_block)); + } + if(m_iq_correction_isSet){ + obj->insert("iqCorrection", QJsonValue(iq_correction)); + } return obj; } @@ -417,6 +437,26 @@ SWGAirspyHFSettings::setAttenuatorSteps(qint32 attenuator_steps) { this->m_attenuator_steps_isSet = true; } +qint32 +SWGAirspyHFSettings::getDcBlock() { + return dc_block; +} +void +SWGAirspyHFSettings::setDcBlock(qint32 dc_block) { + this->dc_block = dc_block; + this->m_dc_block_isSet = true; +} + +qint32 +SWGAirspyHFSettings::getIqCorrection() { + return iq_correction; +} +void +SWGAirspyHFSettings::setIqCorrection(qint32 iq_correction) { + this->iq_correction = iq_correction; + this->m_iq_correction_isSet = true; +} + bool SWGAirspyHFSettings::isSet(){ @@ -439,6 +479,8 @@ SWGAirspyHFSettings::isSet(){ if(m_use_dsp_isSet){ isObjectUpdated = true; break;} if(m_use_lna_isSet){ isObjectUpdated = true; break;} if(m_attenuator_steps_isSet){ isObjectUpdated = true; break;} + if(m_dc_block_isSet){ isObjectUpdated = true; break;} + if(m_iq_correction_isSet){ isObjectUpdated = true; break;} }while(false); return isObjectUpdated; } diff --git a/swagger/sdrangel/code/qt5/client/SWGAirspyHFSettings.h b/swagger/sdrangel/code/qt5/client/SWGAirspyHFSettings.h index c7e6466ff..b8a0f787b 100644 --- a/swagger/sdrangel/code/qt5/client/SWGAirspyHFSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGAirspyHFSettings.h @@ -93,6 +93,12 @@ public: qint32 getAttenuatorSteps(); void setAttenuatorSteps(qint32 attenuator_steps); + qint32 getDcBlock(); + void setDcBlock(qint32 dc_block); + + qint32 getIqCorrection(); + void setIqCorrection(qint32 iq_correction); + virtual bool isSet() override; @@ -148,6 +154,12 @@ private: qint32 attenuator_steps; bool m_attenuator_steps_isSet; + qint32 dc_block; + bool m_dc_block_isSet; + + qint32 iq_correction; + bool m_iq_correction_isSet; + }; }