diff --git a/Readme.md b/Readme.md index e3ddf0074..180711e09 100644 --- a/Readme.md +++ b/Readme.md @@ -53,7 +53,7 @@ If you use your own location for libbladeRF install directory you need to specif

FunCube Dongle

-Both Pro and Pro+ are supported with the plugins in fcdpro and fcdproplus respectively. This is a work in progress. Support of features is still limited for Pro+ (no IF gain, no filter settings) and inadapted for Pro which is just a copy from Pro+ apart from some constants to make it work with Pro. +Both Pro and Pro+ are supported with the plugins in fcdpro and fcdproplus respectively. This is a work in progress. For Pro+ the RF filter selection does not seem to be effective. Perhaps it is derived from the given center frequency internally. Support of features is still inadapted for Pro which is just a copy from Pro+ apart from some constants to make it work with Pro. The control interface is based on qthid and has been built in the software in the fcdhid library. You don't need anything else than libusb support. Library fcdlib is used to store the constants for each dongle type. diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp index d1b56964e..397eb6836 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp @@ -1,3 +1,4 @@ +#include #include "ui_fcdproplusgui.h" #include "plugin/pluginapi.h" #include "gui/colormapper.h" @@ -15,7 +16,7 @@ FCDProPlusGui::FCDProPlusGui(PluginAPI* pluginAPI, QWidget* parent) : ui->setupUi(this); ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold)); - ui->centerFrequency->setValueRange(7, 400000U, 2000000U); + ui->centerFrequency->setValueRange(7, 150U, 2000000U); ui->filterIF->clear(); for (int i = 0; i < FCDProPlusConstants::fcdproplus_if_filter_nb_values(); i++) @@ -96,9 +97,15 @@ bool FCDProPlusGui::handleMessage(const Message& message) void FCDProPlusGui::displaySettings() { ui->centerFrequency->setValue(m_settings.centerFrequency / 1000); - ui->checkBoxR->setChecked(m_settings.rangeLow); ui->checkBoxG->setChecked(m_settings.lnaGain); ui->checkBoxB->setChecked(m_settings.biasT); + ui->mixGain->setChecked(m_settings.mixGain); + ui->ifGain->setValue(m_settings.ifGain); + ui->ifGainText->setText(QString("%1dB").arg(m_settings.ifGain)); + ui->filterIF->setCurrentIndex(m_settings.ifFilterIndex); + ui->filterRF->setCurrentIndex(m_settings.rfFilterIndex); + ui->ppm->setValue(m_settings.LOppmTenths); + ui->ppmText->setText(QString("%1").arg(QString::number(m_settings.LOppmTenths/10.0, 'f', 1))); } void FCDProPlusGui::sendSettings() @@ -120,34 +127,6 @@ void FCDProPlusGui::updateHardware() m_updateTimer.stop(); } -void FCDProPlusGui::on_checkBoxR_stateChanged(int state) -{ - if (state == Qt::Checked) - { - ui->centerFrequency->setValueRange(7, 150U, 240000U); - - if ((ui->centerFrequency->getValue() < 150U) || (ui->centerFrequency->getValue() > 240000U)) - { - ui->centerFrequency->setValue(7000); - m_settings.centerFrequency = 7000 * 1000; - m_settings.rangeLow = true; - } - } - else - { - ui->centerFrequency->setValueRange(7, 400000U, 2000000U); - - if ((ui->centerFrequency->getValue() < 150U) || (ui->centerFrequency->getValue() > 240000U)) - { - ui->centerFrequency->setValue(435000); - m_settings.centerFrequency = 435000 * 1000; - m_settings.rangeLow = false; - } - } - - sendSettings(); -} - void FCDProPlusGui::on_checkBoxG_stateChanged(int state) { m_settings.lnaGain = (state == Qt::Checked); @@ -181,6 +160,14 @@ void FCDProPlusGui::on_filterRF_currentIndexChanged(int index) void FCDProPlusGui::on_ifGain_valueChanged(int value) { m_settings.ifGain = value; + displaySettings(); + sendSettings(); +} + +void FCDProPlusGui::on_ppm_valueChanged(int value) +{ + m_settings.LOppmTenths = value; + displaySettings(); sendSettings(); } diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.h b/plugins/samplesource/fcdproplus/fcdproplusgui.h index 2dbcbdc1e..ebd3e9f88 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.h +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.h @@ -44,13 +44,13 @@ private: private slots: void on_centerFrequency_changed(quint64 value); - void on_checkBoxR_stateChanged(int state); void on_checkBoxG_stateChanged(int state); void on_checkBoxB_stateChanged(int state); void on_mixGain_stateChanged(int state); void on_ifGain_valueChanged(int value); void on_filterRF_currentIndexChanged(int index); void on_filterIF_currentIndexChanged(int index); + void on_ppm_valueChanged(int value); void updateHardware(); }; diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.ui b/plugins/samplesource/fcdproplus/fcdproplusgui.ui index 219da91b8..e3e3ae962 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.ui +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.ui @@ -100,35 +100,33 @@ - - - - - - Mix Gain - - - - - - - Low Range - - - - - + + Activate LNA + - LNA Gain + LNA + + + + + + + Activate mixer gain + + + Mix + + Activate bias tee + Bias T @@ -147,6 +145,12 @@ + + 59 + + + 1 + Qt::Horizontal @@ -161,6 +165,43 @@ + + + + + + LO ppm + + + + + + + LO ppm correction + + + -100 + + + 100 + + + 1 + + + Qt::Horizontal + + + + + + + 0.0 + + + + + diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp index 2f67559b8..a0041065d 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp @@ -51,7 +51,8 @@ FCDProPlusInput::Settings::Settings() : biasT(false), ifGain(0), ifFilterIndex(0), - rfFilterIndex(0) + rfFilterIndex(0), + LOppmTenths(0) { } @@ -64,6 +65,7 @@ void FCDProPlusInput::Settings::resetToDefaults() ifGain = 0; rfFilterIndex = 0; ifFilterIndex = 0; + LOppmTenths = 0; } QByteArray FCDProPlusInput::Settings::serialize() const @@ -71,6 +73,7 @@ QByteArray FCDProPlusInput::Settings::serialize() const FCDProPlusSerializer::FCDData data; data.m_data.m_lnaGain = lnaGain; + data.m_data.m_correction = LOppmTenths; data.m_data.m_RxGain1 = ifGain; data.m_data.m_frequency = centerFrequency; data.m_rangeLow = rangeLow; @@ -98,6 +101,7 @@ bool FCDProPlusInput::Settings::deserialize(const QByteArray& serializedData) bool valid = FCDProPlusSerializer::readSerializedData(serializedData, data); lnaGain = data.m_data.m_lnaGain; + LOppmTenths = data.m_data.m_correction; ifGain = data.m_data.m_RxGain1; centerFrequency = data.m_data.m_frequency; rangeLow = data.m_rangeLow; @@ -255,7 +259,7 @@ void FCDProPlusInput::applySettings(const Settings& settings, bool force) if (m_dev != 0) { - set_lna_gain(settings.lnaGain > 0); + set_lna_gain(settings.lnaGain); } } @@ -265,11 +269,61 @@ void FCDProPlusInput::applySettings(const Settings& settings, bool force) if (m_dev != 0) { - set_bias_t(settings.biasT > 0); + set_bias_t(settings.biasT); } } - if (signalChange) + if ((m_settings.mixGain != settings.mixGain) || force) + { + m_settings.mixGain = settings.mixGain; + + if (m_dev != 0) + { + set_mixer_gain(settings.mixGain); + } + } + + if ((m_settings.ifGain != settings.ifGain) || force) + { + m_settings.ifGain = settings.ifGain; + + if (m_dev != 0) + { + set_if_gain(settings.ifGain); + } + } + + if ((m_settings.ifFilterIndex != settings.ifFilterIndex) || force) + { + m_settings.ifFilterIndex = settings.ifFilterIndex; + + if (m_dev != 0) + { + set_if_filter(settings.ifFilterIndex); + } + } + + if ((m_settings.rfFilterIndex != settings.rfFilterIndex) || force) + { + m_settings.rfFilterIndex = settings.rfFilterIndex; + + if (m_dev != 0) + { + set_rf_filter(settings.rfFilterIndex); + } + } + + if ((m_settings.LOppmTenths != settings.LOppmTenths) || force) + { + m_settings.LOppmTenths = settings.LOppmTenths; + + if (m_dev != 0) + { + set_lo_ppm(); + } + } + + if (signalChange) { DSPSignalNotification *notif = new DSPSignalNotification(fcd_traits::sampleRate, m_settings.centerFrequency); getOutputMessageQueue()->push(notif); @@ -278,6 +332,8 @@ void FCDProPlusInput::applySettings(const Settings& settings, bool force) void FCDProPlusInput::set_center_freq(double freq) { + freq += freq*(((double) m_settings.LOppmTenths)/10000000.0); + if (fcdAppSetFreq(m_dev, freq) == FCD_MODE_NONE) { qDebug("No FCD HID found for frquency change"); @@ -314,7 +370,10 @@ void FCDProPlusInput::set_if_gain(int gain) quint8 cmd_value = gain; - fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_IF_GAIN, &cmd_value, 1); + if (fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_IF_GAIN, &cmd_value, 1) != FCD_MODE_APP) + { + qWarning() << "FCDProPlusInput::set_if_gain: failed to set at " << cmd_value; + } } void FCDProPlusInput::set_if_filter(int filterIndex) @@ -326,7 +385,10 @@ void FCDProPlusInput::set_if_filter(int filterIndex) quint8 cmd_value = FCDProPlusConstants::if_filters[filterIndex].value; - fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_IF_FILTER, &cmd_value, 1); + if (fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_IF_FILTER, &cmd_value, 1) != FCD_MODE_APP) + { + qWarning() << "FCDProPlusInput::set_if_filter: failed to set at " << cmd_value; + } } @@ -339,8 +401,17 @@ void FCDProPlusInput::set_rf_filter(int filterIndex) quint8 cmd_value = FCDProPlusConstants::rf_filters[filterIndex].value; - fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_RF_FILTER, &cmd_value, 1); + if (fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_RF_FILTER, &cmd_value, 1) != FCD_MODE_APP) + { + qWarning() << "FCDProPlusInput::set_rf_filter: failed to set at " << cmd_value; + } +} + +void FCDProPlusInput::set_lo_ppm() +{ + set_center_freq((double) m_settings.centerFrequency); } + diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.h b/plugins/samplesource/fcdproplus/fcdproplusinput.h index b05ddd92e..a7b0b191b 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.h +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.h @@ -42,6 +42,7 @@ public: quint32 ifGain; qint32 ifFilterIndex; qint32 rfFilterIndex; + qint32 LOppmTenths; void resetToDefaults(); QByteArray serialize() const; bool deserialize(const QByteArray& data); @@ -87,6 +88,7 @@ public: void set_if_gain(int gain); void set_rf_filter(int filterIndex); void set_if_filter(int filterIndex); + void set_lo_ppm(); private: void applySettings(const Settings& settings, bool force);