1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-22 17:45:48 -05:00

Proper support of FCD Pro+ interim phase #1

This commit is contained in:
f4exb 2015-09-05 11:46:56 +02:00
parent 863ea359a4
commit 7739db8fbe
11 changed files with 329 additions and 62 deletions

View File

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

62
fcdlib/fcdproplusconst.h Normal file
View File

@ -0,0 +1,62 @@
/*
* fcdproplusconst.h
*
* Created on: Sep 5, 2015
* Author: f4exb
*/
#ifndef FCDLIB_FCDPROPLUSCONST_H_
#define FCDLIB_FCDPROPLUSCONST_H_
#include <string>
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_ */

View File

@ -50,7 +50,7 @@ struct fcd_traits<ProPlus>
static const uint16_t vendorId = 0x04D8; static const uint16_t vendorId = 0x04D8;
static const uint16_t productId = 0xFB31; static const uint16_t productId = 0xFB31;
static const int sampleRate = 192000; static const int sampleRate = 192000;
static const int convBufSize = (1<<13); static const int convBufSize = (1<<12);
static const char *alsaDeviceName; static const char *alsaDeviceName;
static const char *interfaceIID; static const char *interfaceIID;
static const char *displayedName; static const char *displayedName;

View File

@ -31,6 +31,7 @@ public:
void setFont(const QFont& font); void setFont(const QFont& font);
void setBold(bool bold); void setBold(bool bold);
void setColorMapper(ColorMapper colorMapper); void setColorMapper(ColorMapper colorMapper);
quint64 getValue() const { return m_value; }
signals: signals:
void changed(quint64 value); void changed(quint64 value);

View File

@ -3,6 +3,7 @@
#include "gui/colormapper.h" #include "gui/colormapper.h"
#include "dsp/dspengine.h" #include "dsp/dspengine.h"
#include "fcdproplusgui.h" #include "fcdproplusgui.h"
#include "fcdproplusconst.h"
FCDProPlusGui::FCDProPlusGui(PluginAPI* pluginAPI, QWidget* parent) : FCDProPlusGui::FCDProPlusGui(PluginAPI* pluginAPI, QWidget* parent) :
QWidget(parent), QWidget(parent),
@ -12,8 +13,22 @@ FCDProPlusGui::FCDProPlusGui(PluginAPI* pluginAPI, QWidget* parent) :
m_sampleSource(NULL) m_sampleSource(NULL)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::ReverseGold)); 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())); connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
displaySettings(); displaySettings();
@ -81,9 +96,9 @@ bool FCDProPlusGui::handleMessage(const Message& message)
void FCDProPlusGui::displaySettings() void FCDProPlusGui::displaySettings()
{ {
ui->centerFrequency->setValue(m_settings.centerFrequency / 1000); ui->centerFrequency->setValue(m_settings.centerFrequency / 1000);
ui->checkBoxR->setChecked(m_settings.range); ui->checkBoxR->setChecked(m_settings.rangeLow);
ui->checkBoxG->setChecked(m_settings.gain); ui->checkBoxG->setChecked(m_settings.lnaGain);
ui->checkBoxB->setChecked(m_settings.bias); ui->checkBoxB->setChecked(m_settings.biasT);
} }
void FCDProPlusGui::sendSettings() void FCDProPlusGui::sendSettings()
@ -107,19 +122,27 @@ void FCDProPlusGui::updateHardware()
void FCDProPlusGui::on_checkBoxR_stateChanged(int state) 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->setValueRange(7, 150U, 240000U);
if ((ui->centerFrequency->getValue() < 150U) || (ui->centerFrequency->getValue() > 240000U))
{
ui->centerFrequency->setValue(7000); ui->centerFrequency->setValue(7000);
m_settings.centerFrequency = 7000 * 1000; m_settings.centerFrequency = 7000 * 1000;
m_settings.range = 1; m_settings.rangeLow = true;
}
} }
else else
{ {
ui->centerFrequency->setValueRange(7, 64000U, 1900000U); ui->centerFrequency->setValueRange(7, 400000U, 2000000U);
if ((ui->centerFrequency->getValue() < 150U) || (ui->centerFrequency->getValue() > 240000U))
{
ui->centerFrequency->setValue(435000); ui->centerFrequency->setValue(435000);
m_settings.centerFrequency = 435000 * 1000; m_settings.centerFrequency = 435000 * 1000;
m_settings.range = 0; m_settings.rangeLow = false;
}
} }
sendSettings(); sendSettings();
@ -127,28 +150,37 @@ void FCDProPlusGui::on_checkBoxR_stateChanged(int state)
void FCDProPlusGui::on_checkBoxG_stateChanged(int state) void FCDProPlusGui::on_checkBoxG_stateChanged(int state)
{ {
if (state == Qt::Checked) m_settings.lnaGain = (state == Qt::Checked);
{
m_settings.gain = 1;
}
else
{
m_settings.gain = 0;
}
sendSettings(); sendSettings();
} }
void FCDProPlusGui::on_checkBoxB_stateChanged(int state) void FCDProPlusGui::on_checkBoxB_stateChanged(int state)
{ {
if (state == Qt::Checked) m_settings.biasT = (state == Qt::Checked);
{
m_settings.bias = 1;
}
else
{
m_settings.bias = 0;
}
sendSettings(); 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();
}

View File

@ -47,6 +47,10 @@ private slots:
void on_checkBoxR_stateChanged(int state); void on_checkBoxR_stateChanged(int state);
void on_checkBoxG_stateChanged(int state); void on_checkBoxG_stateChanged(int state);
void on_checkBoxB_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(); void updateHardware();
}; };

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>165</width> <width>190</width>
<height>119</height> <height>137</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -102,6 +102,13 @@
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayoutR"> <layout class="QHBoxLayout" name="horizontalLayoutR">
<item>
<widget class="QCheckBox" name="mixGain">
<property name="text">
<string>Mix Gain</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QCheckBox" name="checkBoxR"> <widget class="QCheckBox" name="checkBoxR">
<property name="text"> <property name="text">
@ -129,6 +136,49 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_IF">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>IF gain</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="ifGain">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="ifGainText">
<property name="text">
<string>0 dB</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QComboBox" name="filterRF">
<property name="toolTip">
<string>RF filter</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="filterIF">
<property name="toolTip">
<string>IF filter</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

View File

@ -27,6 +27,7 @@
#include "fcdproplusserializer.h" #include "fcdproplusserializer.h"
#include "fcdproplusthread.h" #include "fcdproplusthread.h"
#include "fcdtraits.h" #include "fcdtraits.h"
#include "fcdproplusconst.h"
MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgConfigureFCD, Message) MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgConfigureFCD, Message)
//MESSAGE_CLASS_DEFINITION(FCDInput::MsgReportFCD, Message) //MESSAGE_CLASS_DEFINITION(FCDInput::MsgReportFCD, Message)
@ -44,28 +45,36 @@ const std::string FCDInput::m_deviceName("hw:CARD=V10");
FCDProPlusInput::Settings::Settings() : FCDProPlusInput::Settings::Settings() :
centerFrequency(435000000), centerFrequency(435000000),
range(0), rangeLow(true),
gain(0), lnaGain(true),
bias(0) mixGain(true),
biasT(false),
ifGain(0),
ifFilterIndex(0),
rfFilterIndex(0)
{ {
} }
void FCDProPlusInput::Settings::resetToDefaults() void FCDProPlusInput::Settings::resetToDefaults()
{ {
centerFrequency = 435000000; centerFrequency = 435000000;
range = 0; rangeLow = true;
gain = 0; lnaGain = true;
bias = 0; biasT = false;
ifGain = 0;
rfFilterIndex = 0;
ifFilterIndex = 0;
} }
QByteArray FCDProPlusInput::Settings::serialize() const QByteArray FCDProPlusInput::Settings::serialize() const
{ {
FCDProPlusSerializer::FCDData data; 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_data.m_frequency = centerFrequency;
data.m_range = range; data.m_rangeLow = rangeLow;
data.m_bias = bias; data.m_biasT = biasT;
QByteArray byteArray; QByteArray byteArray;
@ -88,10 +97,11 @@ bool FCDProPlusInput::Settings::deserialize(const QByteArray& serializedData)
bool valid = FCDProPlusSerializer::readSerializedData(serializedData, data); 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; centerFrequency = data.m_data.m_frequency;
range = data.m_range; rangeLow = data.m_rangeLow;
bias = data.m_bias; biasT = data.m_biasT;
return valid; return valid;
@ -239,23 +249,23 @@ void FCDProPlusInput::applySettings(const Settings& settings, bool force)
signalChange = true; 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) 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) 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); 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);
}

View File

@ -35,9 +35,13 @@ public:
struct Settings { struct Settings {
Settings(); Settings();
quint64 centerFrequency; quint64 centerFrequency;
qint32 range; bool rangeLow;
qint32 gain; bool lnaGain;
qint32 bias; bool mixGain;
bool biasT;
quint32 ifGain;
qint32 ifFilterIndex;
qint32 rfFilterIndex;
void resetToDefaults(); void resetToDefaults();
QByteArray serialize() const; QByteArray serialize() const;
bool deserialize(const QByteArray& data); bool deserialize(const QByteArray& data);
@ -79,6 +83,10 @@ public:
void set_center_freq(double freq); void set_center_freq(double freq);
void set_bias_t(bool on); void set_bias_t(bool on);
void set_lna_gain(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: private:
void applySettings(const Settings& settings, bool force); void applySettings(const Settings& settings, bool force);

View File

@ -24,8 +24,11 @@ void FCDProPlusSerializer::writeSerializedData(const FCDData& data, QByteArray&
SimpleSerializer s(1); SimpleSerializer s(1);
s.writeBlob(1, sampleSourceSerialized); s.writeBlob(1, sampleSourceSerialized);
s.writeS32(2, data.m_bias); s.writeBool(2, data.m_biasT);
s.writeS32(3, data.m_range); 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(); serializedData = s.final();
} }
@ -49,8 +52,11 @@ bool FCDProPlusSerializer::readSerializedData(const QByteArray& serializedData,
int intval; int intval;
d.readBlob(1, &sampleSourceSerialized); d.readBlob(1, &sampleSourceSerialized);
d.readS32(2, &data.m_bias); d.readBool(2, &data.m_biasT, false);
d.readS32(3, &data.m_range); 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); return SampleSourceSerializer::readSerializedData(sampleSourceSerialized, data.m_data);
} }
@ -63,6 +69,9 @@ bool FCDProPlusSerializer::readSerializedData(const QByteArray& serializedData,
void FCDProPlusSerializer::setDefaults(FCDData& data) void FCDProPlusSerializer::setDefaults(FCDData& data)
{ {
data.m_range = 0; data.m_rangeLow = false;
data.m_bias = 0; data.m_biasT = false;
data.m_mixGain = true;
data.m_ifFilterIndex = 0;
data.m_rfFilterIndex = 0;
} }

View File

@ -25,8 +25,11 @@ public:
struct FCDData struct FCDData
{ {
SampleSourceSerializer::Data m_data; SampleSourceSerializer::Data m_data;
qint32 m_bias; bool m_mixGain;
qint32 m_range; bool m_biasT;
bool m_rangeLow;
qint32 m_ifFilterIndex;
qint32 m_rfFilterIndex;
}; };
static void writeSerializedData(const FCDData& data, QByteArray& serializedData); static void writeSerializedData(const FCDData& data, QByteArray& serializedData);