diff --git a/fcdlib/fcdproplusconst.cpp b/fcdlib/fcdproplusconst.cpp new file mode 100644 index 000000000..2bceb8eb1 --- /dev/null +++ b/fcdlib/fcdproplusconst.cpp @@ -0,0 +1,43 @@ +/* + * fcdproplusconst.cpp + * + * Created on: Sep 5, 2015 + * Author: f4exb + */ + +#include "fcdproplusconst.h" + +const fcdproplus_rf_filter FCDProPlusConstants::rf_filters[] = { + {FCDPROPLUS_TRF_0_4, "0-4M"}, + {FCDPROPLUS_TRF_4_8, "4-8M"}, + {FCDPROPLUS_TRF_8_16, "8-16M"}, + {FCDPROPLUS_TRF_16_32, "16-32M"}, + {FCDPROPLUS_TRF_32_75, "32-75M"}, + {FCDPROPLUS_TRF_75_125, "75-125M"}, + {FCDPROPLUS_TRF_125_250, "125-250M"}, + {FCDPROPLUS_TRF_145, "145M"}, + {FCDPROPLUS_TRF_410_875, "410-875M"}, + {FCDPROPLUS_TRF_435, "435M"}, + {FCDPROPLUS_TRF_875_2000, "875M-2G"} +}; + +int FCDProPlusConstants::fcdproplus_rf_filter_nb_values() +{ + return sizeof(rf_filters) / sizeof(fcdproplus_rf_filter); +} + +const fcdproplus_if_filter FCDProPlusConstants::if_filters[] = { + {FCDPROPLUS_TIF_200KHZ, "200k"}, + {FCDPROPLUS_TIF_300KHZ, "300k"}, + {FCDPROPLUS_TIF_600KHZ, "600k"}, + {FCDPROPLUS_TIF_1536KHZ, "1.5M"}, + {FCDPROPLUS_TIF_5MHZ, "5M"}, + {FCDPROPLUS_TIF_6MHZ, "6M"}, + {FCDPROPLUS_TIF_7MHZ, "7M"}, + {FCDPROPLUS_TIF_8MHZ, "8M"} +}; + +int FCDProPlusConstants::fcdproplus_if_filter_nb_values() +{ + return sizeof(if_filters) / sizeof(fcdproplus_if_filter); +} diff --git a/fcdlib/fcdproplusconst.h b/fcdlib/fcdproplusconst.h new file mode 100644 index 000000000..1000bf0e4 --- /dev/null +++ b/fcdlib/fcdproplusconst.h @@ -0,0 +1,62 @@ +/* + * fcdproplusconst.h + * + * Created on: Sep 5, 2015 + * Author: f4exb + */ + +#ifndef FCDLIB_FCDPROPLUSCONST_H_ +#define FCDLIB_FCDPROPLUSCONST_H_ + +#include + +typedef enum +{ + FCDPROPLUS_TRF_0_4, + FCDPROPLUS_TRF_4_8, + FCDPROPLUS_TRF_8_16, + FCDPROPLUS_TRF_16_32, + FCDPROPLUS_TRF_32_75, + FCDPROPLUS_TRF_75_125, + FCDPROPLUS_TRF_125_250, + FCDPROPLUS_TRF_145, + FCDPROPLUS_TRF_410_875, + FCDPROPLUS_TRF_435, + FCDPROPLUS_TRF_875_2000 +} fcdproplus_rf_filter_value; + +typedef enum +{ + FCDPROPLUS_TIF_200KHZ=0, + FCDPROPLUS_TIF_300KHZ=1, + FCDPROPLUS_TIF_600KHZ=2, + FCDPROPLUS_TIF_1536KHZ=3, + FCDPROPLUS_TIF_5MHZ=4, + FCDPROPLUS_TIF_6MHZ=5, + FCDPROPLUS_TIF_7MHZ=6, + FCDPROPLUS_TIF_8MHZ=7 +} fcdproplus_if_filter_value; + +typedef struct +{ + fcdproplus_rf_filter_value value; + std::string label; +} fcdproplus_rf_filter; + +typedef struct +{ + fcdproplus_if_filter_value value; + std::string label; +} fcdproplus_if_filter; + +class FCDProPlusConstants +{ +public: + static const fcdproplus_rf_filter rf_filters[]; + static const fcdproplus_if_filter if_filters[]; + static int fcdproplus_rf_filter_nb_values(); + static int fcdproplus_if_filter_nb_values(); +}; + + +#endif /* FCDLIB_FCDPROPLUSCONST_H_ */ diff --git a/fcdlib/fcdtraits.h b/fcdlib/fcdtraits.h index a7f3aafb0..82b710c69 100644 --- a/fcdlib/fcdtraits.h +++ b/fcdlib/fcdtraits.h @@ -50,7 +50,7 @@ struct fcd_traits static const uint16_t vendorId = 0x04D8; static const uint16_t productId = 0xFB31; static const int sampleRate = 192000; - static const int convBufSize = (1<<13); + static const int convBufSize = (1<<12); static const char *alsaDeviceName; static const char *interfaceIID; static const char *displayedName; diff --git a/include-gpl/gui/valuedial.h b/include-gpl/gui/valuedial.h index 4cb82f9cc..28db2a2bb 100644 --- a/include-gpl/gui/valuedial.h +++ b/include-gpl/gui/valuedial.h @@ -31,6 +31,7 @@ public: void setFont(const QFont& font); void setBold(bool bold); void setColorMapper(ColorMapper colorMapper); + quint64 getValue() const { return m_value; } signals: void changed(quint64 value); diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp index c6519cd1a..d1b56964e 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp @@ -3,6 +3,7 @@ #include "gui/colormapper.h" #include "dsp/dspengine.h" #include "fcdproplusgui.h" +#include "fcdproplusconst.h" FCDProPlusGui::FCDProPlusGui(PluginAPI* pluginAPI, QWidget* parent) : QWidget(parent), @@ -12,8 +13,22 @@ FCDProPlusGui::FCDProPlusGui(PluginAPI* pluginAPI, QWidget* parent) : m_sampleSource(NULL) { ui->setupUi(this); + ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold)); - ui->centerFrequency->setValueRange(7, 64000U, 1700000U); + ui->centerFrequency->setValueRange(7, 400000U, 2000000U); + + ui->filterIF->clear(); + for (int i = 0; i < FCDProPlusConstants::fcdproplus_if_filter_nb_values(); i++) + { + ui->filterIF->addItem(QString(FCDProPlusConstants::if_filters[i].label.c_str()), i); + } + + ui->filterRF->clear(); + for (int i = 0; i < FCDProPlusConstants::fcdproplus_rf_filter_nb_values(); i++) + { + ui->filterRF->addItem(QString(FCDProPlusConstants::rf_filters[i].label.c_str()), i); + } + connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware())); displaySettings(); @@ -81,9 +96,9 @@ bool FCDProPlusGui::handleMessage(const Message& message) void FCDProPlusGui::displaySettings() { ui->centerFrequency->setValue(m_settings.centerFrequency / 1000); - ui->checkBoxR->setChecked(m_settings.range); - ui->checkBoxG->setChecked(m_settings.gain); - ui->checkBoxB->setChecked(m_settings.bias); + ui->checkBoxR->setChecked(m_settings.rangeLow); + ui->checkBoxG->setChecked(m_settings.lnaGain); + ui->checkBoxB->setChecked(m_settings.biasT); } void FCDProPlusGui::sendSettings() @@ -107,19 +122,27 @@ void FCDProPlusGui::updateHardware() void FCDProPlusGui::on_checkBoxR_stateChanged(int state) { - if (state == Qt::Checked) // FIXME: this is for the Pro+ version only! + if (state == Qt::Checked) { ui->centerFrequency->setValueRange(7, 150U, 240000U); - ui->centerFrequency->setValue(7000); - m_settings.centerFrequency = 7000 * 1000; - m_settings.range = 1; + + 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, 64000U, 1900000U); - ui->centerFrequency->setValue(435000); - m_settings.centerFrequency = 435000 * 1000; - m_settings.range = 0; + 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(); @@ -127,28 +150,37 @@ void FCDProPlusGui::on_checkBoxR_stateChanged(int state) void FCDProPlusGui::on_checkBoxG_stateChanged(int state) { - if (state == Qt::Checked) - { - m_settings.gain = 1; - } - else - { - m_settings.gain = 0; - } - + m_settings.lnaGain = (state == Qt::Checked); sendSettings(); } void FCDProPlusGui::on_checkBoxB_stateChanged(int state) { - if (state == Qt::Checked) - { - m_settings.bias = 1; - } - else - { - m_settings.bias = 0; - } - + m_settings.biasT = (state == Qt::Checked); sendSettings(); } + +void FCDProPlusGui::on_mixGain_stateChanged(int state) +{ + m_settings.mixGain = (state == Qt::Checked); + sendSettings(); +} + +void FCDProPlusGui::on_filterIF_currentIndexChanged(int index) +{ + m_settings.ifFilterIndex = index; + sendSettings(); +} + +void FCDProPlusGui::on_filterRF_currentIndexChanged(int index) +{ + m_settings.rfFilterIndex = index; + sendSettings(); +} + +void FCDProPlusGui::on_ifGain_valueChanged(int value) +{ + m_settings.ifGain = value; + sendSettings(); +} + diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.h b/plugins/samplesource/fcdproplus/fcdproplusgui.h index cb8896008..2dbcbdc1e 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.h +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.h @@ -47,6 +47,10 @@ private slots: 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 updateHardware(); }; diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.ui b/plugins/samplesource/fcdproplus/fcdproplusgui.ui index 5526d38c7..219da91b8 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.ui +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.ui @@ -6,8 +6,8 @@ 0 0 - 165 - 119 + 190 + 137 @@ -102,6 +102,13 @@ + + + + Mix Gain + + + @@ -129,6 +136,49 @@ + + + + + + IF gain + + + + + + + Qt::Horizontal + + + + + + + 0 dB + + + + + + + + + + + RF filter + + + + + + + IF filter + + + + + diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp index 245a0af16..2f67559b8 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp @@ -27,6 +27,7 @@ #include "fcdproplusserializer.h" #include "fcdproplusthread.h" #include "fcdtraits.h" +#include "fcdproplusconst.h" MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgConfigureFCD, Message) //MESSAGE_CLASS_DEFINITION(FCDInput::MsgReportFCD, Message) @@ -44,28 +45,36 @@ const std::string FCDInput::m_deviceName("hw:CARD=V10"); FCDProPlusInput::Settings::Settings() : centerFrequency(435000000), - range(0), - gain(0), - bias(0) + rangeLow(true), + lnaGain(true), + mixGain(true), + biasT(false), + ifGain(0), + ifFilterIndex(0), + rfFilterIndex(0) { } void FCDProPlusInput::Settings::resetToDefaults() { centerFrequency = 435000000; - range = 0; - gain = 0; - bias = 0; + rangeLow = true; + lnaGain = true; + biasT = false; + ifGain = 0; + rfFilterIndex = 0; + ifFilterIndex = 0; } QByteArray FCDProPlusInput::Settings::serialize() const { FCDProPlusSerializer::FCDData data; - data.m_data.m_lnaGain = gain; + data.m_data.m_lnaGain = lnaGain; + data.m_data.m_RxGain1 = ifGain; data.m_data.m_frequency = centerFrequency; - data.m_range = range; - data.m_bias = bias; + data.m_rangeLow = rangeLow; + data.m_biasT = biasT; QByteArray byteArray; @@ -88,10 +97,11 @@ bool FCDProPlusInput::Settings::deserialize(const QByteArray& serializedData) bool valid = FCDProPlusSerializer::readSerializedData(serializedData, data); - gain = data.m_data.m_lnaGain; + lnaGain = data.m_data.m_lnaGain; + ifGain = data.m_data.m_RxGain1; centerFrequency = data.m_data.m_frequency; - range = data.m_range; - bias = data.m_bias; + rangeLow = data.m_rangeLow; + biasT = data.m_biasT; return valid; @@ -239,23 +249,23 @@ void FCDProPlusInput::applySettings(const Settings& settings, bool force) signalChange = true; } - if ((m_settings.gain != settings.gain) || force) + if ((m_settings.lnaGain != settings.lnaGain) || force) { - m_settings.gain = settings.gain; + m_settings.lnaGain = settings.lnaGain; if (m_dev != 0) { - set_lna_gain(settings.gain > 0); + set_lna_gain(settings.lnaGain > 0); } } - if ((m_settings.bias != settings.bias) || force) + if ((m_settings.biasT != settings.biasT) || force) { - m_settings.bias = settings.bias; + m_settings.biasT = settings.biasT; if (m_dev != 0) { - set_bias_t(settings.bias > 0); + set_bias_t(settings.biasT > 0); } } @@ -288,4 +298,49 @@ void FCDProPlusInput::set_lna_gain(bool on) fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_LNA_GAIN, &cmd, 1); } +void FCDProPlusInput::set_mixer_gain(bool on) +{ + quint8 cmd = on ? 1 : 0; + + fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_MIXER_GAIN, &cmd, 1); +} + +void FCDProPlusInput::set_if_gain(int gain) +{ + if (gain < 0) + { + return; + } + + quint8 cmd_value = gain; + + fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_IF_GAIN, &cmd_value, 1); +} + +void FCDProPlusInput::set_if_filter(int filterIndex) +{ + if ((filterIndex < 0) || (filterIndex >= FCDProPlusConstants::fcdproplus_if_filter_nb_values())) + { + return; + } + + quint8 cmd_value = FCDProPlusConstants::if_filters[filterIndex].value; + + fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_IF_FILTER, &cmd_value, 1); +} + + +void FCDProPlusInput::set_rf_filter(int filterIndex) +{ + if ((filterIndex < 0) || (filterIndex >= FCDProPlusConstants::fcdproplus_rf_filter_nb_values())) + { + return; + } + + quint8 cmd_value = FCDProPlusConstants::rf_filters[filterIndex].value; + + fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_RF_FILTER, &cmd_value, 1); +} + + diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.h b/plugins/samplesource/fcdproplus/fcdproplusinput.h index 9479cb319..b05ddd92e 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.h +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.h @@ -35,9 +35,13 @@ public: struct Settings { Settings(); quint64 centerFrequency; - qint32 range; - qint32 gain; - qint32 bias; + bool rangeLow; + bool lnaGain; + bool mixGain; + bool biasT; + quint32 ifGain; + qint32 ifFilterIndex; + qint32 rfFilterIndex; void resetToDefaults(); QByteArray serialize() const; bool deserialize(const QByteArray& data); @@ -79,6 +83,10 @@ public: void set_center_freq(double freq); void set_bias_t(bool on); void set_lna_gain(bool on); + void set_mixer_gain(bool on); + void set_if_gain(int gain); + void set_rf_filter(int filterIndex); + void set_if_filter(int filterIndex); private: void applySettings(const Settings& settings, bool force); diff --git a/plugins/samplesource/fcdproplus/fcdproplusserializer.cpp b/plugins/samplesource/fcdproplus/fcdproplusserializer.cpp index b4151727c..7de4404ba 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusserializer.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusserializer.cpp @@ -24,8 +24,11 @@ void FCDProPlusSerializer::writeSerializedData(const FCDData& data, QByteArray& SimpleSerializer s(1); s.writeBlob(1, sampleSourceSerialized); - s.writeS32(2, data.m_bias); - s.writeS32(3, data.m_range); + s.writeBool(2, data.m_biasT); + s.writeBool(3, data.m_rangeLow); + s.writeBool(4, data.m_mixGain); + s.writeS32(5, data.m_ifFilterIndex); + s.writeS32(6, data.m_rfFilterIndex); serializedData = s.final(); } @@ -49,8 +52,11 @@ bool FCDProPlusSerializer::readSerializedData(const QByteArray& serializedData, int intval; d.readBlob(1, &sampleSourceSerialized); - d.readS32(2, &data.m_bias); - d.readS32(3, &data.m_range); + d.readBool(2, &data.m_biasT, false); + d.readBool(3, &data.m_rangeLow, false); + d.readBool(4, &data.m_mixGain, true); + d.readS32(5, &data.m_ifFilterIndex, 0); + d.readS32(6, &data.m_rfFilterIndex, 0); return SampleSourceSerializer::readSerializedData(sampleSourceSerialized, data.m_data); } @@ -63,6 +69,9 @@ bool FCDProPlusSerializer::readSerializedData(const QByteArray& serializedData, void FCDProPlusSerializer::setDefaults(FCDData& data) { - data.m_range = 0; - data.m_bias = 0; + data.m_rangeLow = false; + data.m_biasT = false; + data.m_mixGain = true; + data.m_ifFilterIndex = 0; + data.m_rfFilterIndex = 0; } diff --git a/plugins/samplesource/fcdproplus/fcdproplusserializer.h b/plugins/samplesource/fcdproplus/fcdproplusserializer.h index ffd7f2b02..866a399c9 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusserializer.h +++ b/plugins/samplesource/fcdproplus/fcdproplusserializer.h @@ -25,8 +25,11 @@ public: struct FCDData { SampleSourceSerializer::Data m_data; - qint32 m_bias; - qint32 m_range; + bool m_mixGain; + bool m_biasT; + bool m_rangeLow; + qint32 m_ifFilterIndex; + qint32 m_rfFilterIndex; }; static void writeSerializedData(const FCDData& data, QByteArray& serializedData);