AirspyHF: implemented local DC and IQ imbalance corrections

This commit is contained in:
f4exb 2019-01-14 09:25:08 +01:00
parent 013e512948
commit a0478d0f73
12 changed files with 182 additions and 10 deletions

View File

@ -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";

View File

@ -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);

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>324</width>
<width>320</width>
<height>160</height>
</rect>
</property>
@ -235,6 +235,26 @@
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="dcOffset">
<property name="toolTip">
<string>DC component block (internal DSP)</string>
</property>
<property name="text">
<string>DC</string>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="iqImbalance">
<property name="toolTip">
<string>IQ imbalance correction (internal DSP)</string>
</property>
<property name="text">
<string>IQ</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -420,12 +440,21 @@
</item>
<item>
<widget class="QComboBox" name="agc">
<property name="minimumSize">
<size>
<width>55</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>55</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>AGC mode and threshold (HF only)</string>
</property>
<item>
<property name="text">
<string>Off</string>
@ -445,6 +474,9 @@
</item>
<item>
<widget class="ButtonSwitch" name="lna">
<property name="toolTip">
<string>LNA on/off (HF only)</string>
</property>
<property name="text">
<string>LNA</string>
</property>
@ -459,12 +491,21 @@
</item>
<item>
<widget class="QComboBox" name="att">
<property name="minimumSize">
<size>
<width>42</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<width>42</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Attenuator (AGC off and HF only)</string>
</property>
<item>
<property name="text">
<string>0</string>
@ -534,6 +575,9 @@
</item>
<item>
<widget class="ButtonSwitch" name="dsp">
<property name="toolTip">
<string>Toggle libairspyhf DSP on/off</string>
</property>
<property name="text">
<string>DSP</string>
</property>

View File

@ -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<QString>& 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)

View File

@ -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;
}

View File

@ -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();

View File

@ -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:
</div>
<div id="generator">
<div class="content">
Generated 2019-01-14T01:23:06.065+01:00
Generated 2019-01-14T08:33:10.665+01:00
</div>
</div>
</div>

View File

@ -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

View File

@ -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

View File

@ -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:
</div>
<div id="generator">
<div class="content">
Generated 2019-01-14T01:23:06.065+01:00
Generated 2019-01-14T08:33:10.665+01:00
</div>
</div>
</div>

View File

@ -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;
}

View File

@ -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;
};
}