PluoSDR: debug (1)

This commit is contained in:
f4exb 2017-09-09 03:09:17 +02:00
parent 3c20b02602
commit aa047c77cc
10 changed files with 523 additions and 187 deletions

View File

@ -19,7 +19,7 @@
const uint64_t DevicePlutoSDR::loLowLimitFreq = 70000000UL; // 70 MHz: take AD9364 specs
const uint64_t DevicePlutoSDR::loHighLimitFreq = 6000000000UL; // 6 GHz: take AD9364 specs
const uint32_t DevicePlutoSDR::srLowLimitFreq = 200000; // 200 kS/s
const uint32_t DevicePlutoSDR::srLowLimitFreq = 2100000; // 2.1 MS/s empirical
const uint32_t DevicePlutoSDR::srHighLimitFreq = 20000000; // 20 MS/s: take AD9363 speces
const uint32_t DevicePlutoSDR::bbLPRxLowLimitFreq = 200000; // 200 kHz

View File

@ -79,6 +79,7 @@ void DevicePlutoSDRBox::set_params(DeviceType devType,
const char *attr = 0;
std::size_t pos;
int ret;
int type;
pos = it->find('=');
@ -101,15 +102,35 @@ void DevicePlutoSDRBox::set_params(DeviceType devType,
if (chn) {
ret = iio_channel_attr_write(chn, attr, val.c_str());
type = 0;
} else if (iio_device_find_attr(dev, attr)) {
ret = iio_device_attr_write(dev, attr, val.c_str());
type = 1;
} else {
ret = iio_device_debug_attr_write(dev, attr, val.c_str());
type = 2;
}
if (ret < 0)
{
std::cerr << "DevicePlutoSDRBox::set_params: Unable to write attribute " << key << ": " << ret << std::endl;
std::string item;
switch (type)
{
case 0:
item = "channel";
break;
case 1:
item = "device";
break;
case 2:
item = "debug";
break;
default:
item = "unknown";
break;
}
std::cerr << "DevicePlutoSDRBox::set_params: Unable to write " << item << " attribute " << key << "=" << val << ": " << ret << std::endl;
}
}
}
@ -352,6 +373,7 @@ bool DevicePlutoSDRBox::getRxSampleRates(SampleRates& sampleRates)
std::string srStr;
if (get_param(DEVICE_PHY, "rx_path_rates", srStr)) {
qDebug("DevicePlutoSDRBox::getRxSampleRates: %s", srStr.c_str());
return parseSampleRates(srStr, sampleRates);
} else {
return false;
@ -382,12 +404,12 @@ bool DevicePlutoSDRBox::parseSampleRates(const std::string& rateStr, SampleRates
{
try
{
sampleRates.m_bbRate = boost::lexical_cast<uint32_t>(desc_match[1]) + 1;
sampleRates.m_addaConnvRate = boost::lexical_cast<uint32_t>(desc_match[2]) + 1;
sampleRates.m_hb3Rate = boost::lexical_cast<uint32_t>(desc_match[3]) + 1;
sampleRates.m_hb2Rate = boost::lexical_cast<uint32_t>(desc_match[4]) + 1;
sampleRates.m_hb1Rate = boost::lexical_cast<uint32_t>(desc_match[5]) + 1;
sampleRates.m_firRate = boost::lexical_cast<uint32_t>(desc_match[6]) + 1;
sampleRates.m_bbRate = boost::lexical_cast<uint32_t>(desc_match[1]);
sampleRates.m_addaConnvRate = boost::lexical_cast<uint32_t>(desc_match[2]);
sampleRates.m_hb3Rate = boost::lexical_cast<uint32_t>(desc_match[3]);
sampleRates.m_hb2Rate = boost::lexical_cast<uint32_t>(desc_match[4]);
sampleRates.m_hb1Rate = boost::lexical_cast<uint32_t>(desc_match[5]);
sampleRates.m_firRate = boost::lexical_cast<uint32_t>(desc_match[6]);
return true;
}
catch (const boost::bad_lexical_cast &e)
@ -402,65 +424,106 @@ bool DevicePlutoSDRBox::parseSampleRates(const std::string& rateStr, SampleRates
}
}
void DevicePlutoSDRBox::setFIR(DeviceUse use, uint32_t intdec, uint32_t bw, int gain)
void DevicePlutoSDRBox::setSampleRate(uint32_t sampleRate)
{
char buff[100];
std::vector<std::string> params;
snprintf(buff, sizeof(buff), "in_voltage_sampling_frequency=%d", sampleRate);
params.push_back(std::string(buff));
snprintf(buff, sizeof(buff), "out_voltage_sampling_frequency=%d", sampleRate);
params.push_back(std::string(buff));
set_params(DEVICE_PHY, params); // set end point frequency first
m_devSampleRate = sampleRate;
}
void DevicePlutoSDRBox::setFIR(uint32_t log2IntDec, uint32_t bw, int gain)
{
SampleRates sampleRates;
std::ostringstream ostr;
uint32_t nbTaps;
double normalizedBW;
uint32_t intdec = 1<<(log2IntDec > 2 ? 2 : log2IntDec);
// set a dummy minimal filter first to get the sample rates right
formatFIRHeader(ostr, use, intdec, gain);
setFIREnable(false); // disable first
formatFIRHeader(ostr, intdec, gain);
formatFIRCoefficients(ostr, 16, 0.5);
setFilter(ostr.str());
ostr.str(""); // reset string stream
if (use == USE_RX)
{
if (!getRxSampleRates(sampleRates)) {
return;
}
setFIREnable(true); // re-enable
uint32_t nbGroups = sampleRates.m_addaConnvRate / 16;
nbTaps = nbGroups*8 > 128 ? 128 : nbGroups*8;
normalizedBW = ((float) bw) / sampleRates.m_hb1Rate;
normalizedBW = normalizedBW < 0.1 ? 0.1 : normalizedBW > 0.9 ? 0.9 : normalizedBW;
if (!getRxSampleRates(sampleRates)) {
return;
}
else
{
if (!getTxSampleRates(sampleRates)) {
return;
}
uint32_t nbGroups = sampleRates.m_addaConnvRate / 16;
nbTaps = nbGroups*8 > 128 ? 128 : nbGroups*8;
nbTaps = intdec == 1 ? (nbTaps > 64 ? 64 : nbTaps) : nbTaps;
normalizedBW = ((float) bw) / sampleRates.m_hb1Rate;
normalizedBW = normalizedBW < 0.1 ? 0.1 : normalizedBW > 0.9 ? 0.9 : normalizedBW;
}
setFIREnable(false); // disable again
uint32_t nbGroups = sampleRates.m_addaConnvRate / 16;
nbTaps = nbGroups*8 > 128 ? 128 : nbGroups*8;
nbTaps = intdec == 1 ? (nbTaps > 64 ? 64 : nbTaps) : nbTaps;
normalizedBW = ((float) bw) / sampleRates.m_hb1Rate;
normalizedBW = normalizedBW < 0.1 ? 0.1 : normalizedBW > 0.9 ? 0.9 : normalizedBW;
qDebug("DevicePlutoSDRBox::setFIR: intdec: %u gain: %d nbTaps: %u BWin: %u BW: %f (%f)",
intdec,
gain,
nbTaps,
bw,
normalizedBW*sampleRates.m_hb1Rate,
normalizedBW);
// set the right filter
formatFIRHeader(ostr, use, intdec, gain);
formatFIRHeader(ostr, intdec, gain);
formatFIRCoefficients(ostr, nbTaps, normalizedBW);
setFilter(ostr.str());
m_lpfFIRlog2Decim = log2IntDec;
m_lpfFIRBW = bw;
m_lpfFIRGain = gain;
}
void DevicePlutoSDRBox::formatFIRHeader(std::ostringstream& ostr, DeviceUse use, uint32_t intdec, int32_t gain)
void DevicePlutoSDRBox::setFIREnable(bool enable)
{
ostr << (use == USE_RX ? "RX 1" : "TX 1") << " GAIN " << gain << " DEC " << intdec << std::endl;
char buff[100];
std::vector<std::string> params;
snprintf(buff, sizeof(buff), "in_out_voltage_filter_fir_en=%d", enable ? 1 : 0);
params.push_back(std::string(buff));
set_params(DEVICE_PHY, params);
m_lpfFIREnable = enable;
}
void DevicePlutoSDRBox::setLOPPMTenths(int ppmTenths)
{
char buff[100];
std::vector<std::string> params;
int64_t newXO = m_xoInitial + ((m_xoInitial*ppmTenths) / 10000000L);
snprintf(buff, sizeof(buff), "xo_correction=%ld", newXO);
params.push_back(std::string(buff));
set_params(DEVICE_PHY, params);
m_LOppmTenths = ppmTenths;
}
void DevicePlutoSDRBox::formatFIRHeader(std::ostringstream& ostr,uint32_t intdec, int32_t gain)
{
ostr << "RX 3 GAIN " << gain << " DEC " << intdec << std::endl;
ostr << "TX 3 GAIN " << gain << " INT " << intdec << std::endl;
}
void DevicePlutoSDRBox::formatFIRCoefficients(std::ostringstream& ostr, uint32_t nbTaps, double normalizedBW)
{
double *fcoeffs = new double[nbTaps];
WFIR::BasicFIR(fcoeffs, nbTaps, WFIR::LPF, 0.0, normalizedBW, WFIR::wtBLACKMAN_HARRIS, 0.0);
WFIR::BasicFIR(fcoeffs, nbTaps, WFIR::LPF, normalizedBW, 0.0, WFIR::wtBLACKMAN_HARRIS, 0.0);
for (unsigned int i = 0; i < nbTaps; i++) {
ostr << (uint16_t) (fcoeffs[i] * 32768.0) << std::endl;
ostr << (int16_t) (fcoeffs[i] * 32768.0) << ", " << (int16_t) (fcoeffs[i] * 32768.0) << std::endl;
}
delete[] fcoeffs;
}
void DevicePlutoSDRBox::getXO()
@ -477,4 +540,41 @@ void DevicePlutoSDRBox::getXO()
}
}
bool DevicePlutoSDRBox::getRSSI(std::string& rssiStr, unsigned int chan)
{
chan = chan % 2;
char buff[20];
snprintf(buff, sizeof(buff), "in_voltage%d_rssi", chan);
return get_param(DEVICE_PHY, buff, rssiStr);
}
bool DevicePlutoSDRBox::fetchTemp()
{
std::string temp_mC_str;
if (get_param(DEVICE_PHY, "in_temp0_input", temp_mC_str))
{
try
{
uint32_t temp_mC = boost::lexical_cast<uint32_t>(temp_mC_str);
m_temp = temp_mC / 1000.0;
return true;
}
catch (const boost::bad_lexical_cast &e)
{
std::cerr << "PlutoSDRDevice::getTemp: bad conversion to numeric" << std::endl;
return false;
}
}
else
{
return false;
}
}
bool DevicePlutoSDRBox::getRateGovernors(std::string& rateGovernors)
{
return get_param(DEVICE_PHY, "trx_rate_governor", rateGovernors);
}

View File

@ -52,6 +52,13 @@ public:
uint32_t m_firRate; //!< Rate of FIR filter (Rx: out, Tx: in) - this is the host/device communication sample rate
};
uint64_t m_devSampleRate; //!< Host interface sample rate
int32_t m_LOppmTenths; //!< XO correction
bool m_lpfFIREnable; //!< enable digital lowpass FIR filter
float m_lpfFIRBW; //!< digital lowpass FIR filter bandwidth (Hz)
uint32_t m_lpfFIRlog2Decim; //!< digital lowpass FIR filter log2 of decimation factor (0..2)
int m_lpfFIRGain; //!< digital lowpass FIR filter gain (dB)
DevicePlutoSDRBox(const std::string& uri);
~DevicePlutoSDRBox();
bool isValid() const { return m_valid; }
@ -80,8 +87,14 @@ public:
char* txBufferFirst();
bool getRxSampleRates(SampleRates& sampleRates);
bool getTxSampleRates(SampleRates& sampleRates);
void setFIR(DeviceUse use, uint32_t intdec, uint32_t bw, int gain);
int64_t getInitialXO() const { return m_xoInitial; }
void setSampleRate(uint32_t sampleRate);
void setFIR(uint32_t intdec, uint32_t bw, int gain);
void setFIREnable(bool enable);
void setLOPPMTenths(int ppmTenths);
bool getRSSI(std::string& rssiStr, unsigned int chan);
bool fetchTemp();
float getTemp() const { return m_temp; }
bool getRateGovernors(std::string& rateGovernors);
private:
struct iio_context *m_ctx;
@ -94,10 +107,11 @@ private:
struct iio_buffer *m_txBuf;
bool m_valid;
int64_t m_xoInitial;
float m_temp;
bool parseSampleRates(const std::string& rateStr, SampleRates& sampleRates);
void setFilter(const std::string& filterConfigStr);
void formatFIRHeader(std::ostringstream& str, DeviceUse use, uint32_t intdec, int32_t gain);
void formatFIRHeader(std::ostringstream& str, uint32_t intdec, int32_t gain);
void formatFIRCoefficients(std::ostringstream& str, uint32_t nbTaps, double normalizedBW);
void getXO();
};

View File

@ -28,6 +28,7 @@
#define PLUTOSDR_BLOCKSIZE (1024*1024) //complex samples per buffer (must be multiple of 64)
MESSAGE_CLASS_DEFINITION(PlutoSDRInput::MsgConfigurePlutoSDR, Message)
MESSAGE_CLASS_DEFINITION(PlutoSDRInput::MsgFileRecord, Message)
PlutoSDRInput::PlutoSDRInput(DeviceSourceAPI *deviceAPI) :
@ -38,17 +39,23 @@ PlutoSDRInput::PlutoSDRInput(DeviceSourceAPI *deviceAPI) :
m_plutoRxBuffer(0),
m_plutoSDRInputThread(0)
{
suspendBuddies();
openDevice();
resumeBuddies();
char recFileNameCStr[30];
sprintf(recFileNameCStr, "test_%d.sdriq", m_deviceAPI->getDeviceUID());
m_fileSink = new FileRecord(std::string(recFileNameCStr));
m_deviceAPI->addSink(m_fileSink);
}
PlutoSDRInput::~PlutoSDRInput()
{
m_deviceAPI->removeSink(m_fileSink);
delete m_fileSink;
suspendBuddies();
closeDevice();
resumeBuddies();
}
bool PlutoSDRInput::start()
@ -247,20 +254,21 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo
bool suspendOwnThread = false;
bool ownThreadWasRunning = false;
bool suspendAllOtherThreads = false; // All others means Tx in fact
bool firFilterSet = false;
DevicePlutoSDRBox *plutoBox = m_deviceShared.m_deviceParams->getBox();
// determine if buddies threads or own thread need to be suspended
// change of global baseband sample rate affecting all buddies can occur if
// changes affecting all buddies can occur if
// - device to host sample rate is changed
// - rate governor is changed
// - FIR filter decimation is changed
// - FIR filter is enabled or disabled
// - FIR filter is changed
// - LO correction is changed
if ((m_settings.m_devSampleRate != settings.m_devSampleRate) ||
(m_settings.m_rateGovernor != settings.m_rateGovernor) ||
(m_settings.m_lpfFIREnable != settings.m_lpfFIREnable) ||
(m_settings.m_lpfFIRlog2Decim != settings.m_lpfFIRlog2Decim) ||
(m_settings.m_lpfFIREnable != settings.m_lpfFIREnable) || force)
(settings.m_lpfFIRBW != m_settings.m_lpfFIRBW) ||
(settings.m_lpfFIRGain != m_settings.m_lpfFIRGain) ||
(m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force)
{
suspendAllOtherThreads = true;
suspendOwnThread = true;
@ -307,47 +315,16 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo
m_deviceAPI->configureCorrections(settings.m_dcBlock, m_settings.m_iqCorrection);
}
// Change affecting device sample rate chain potentially affecting other buddies device/host sample rate
// Change affecting device sample rate chain and other buddies
if ((m_settings.m_devSampleRate != settings.m_devSampleRate) ||
(m_settings.m_rateGovernor != settings.m_rateGovernor) ||
(m_settings.m_lpfFIREnable != settings.m_lpfFIREnable) ||
(m_settings.m_lpfFIRlog2Decim != settings.m_lpfFIRlog2Decim) ||
(m_settings.m_lpfFIREnable != settings.m_lpfFIREnable) || force)
(settings.m_lpfFIRBW != m_settings.m_lpfFIRBW) ||
(settings.m_lpfFIRGain != m_settings.m_lpfFIRGain) || force)
{
std::vector<std::string> params;
params.push_back(QString(tr("in_voltage_sampling_frequency=%1").arg(settings.m_devSampleRate)).toStdString());
QString rateGovStr;
PlutoSDRInputSettings::translateGovernor(settings.m_rateGovernor, rateGovStr);
params.push_back(QString(tr("trx_rate_governor=%1").arg(rateGovStr)).toStdString());
plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); // set end point frequency and rate governor first
// Unless unconditionally forced to change settings change FIR settings if FIR is enabled AND
// - FIR was not enabled before OR
// - Host interface sample rate has changed OR
// - Decimation chain rate governor has changed OR
// - FIR decimation has changed
if ((settings.m_lpfFIREnable && (!m_settings.m_lpfFIREnable
|| (m_settings.m_devSampleRate != settings.m_devSampleRate)
|| (m_settings.m_rateGovernor != settings.m_rateGovernor)
|| (m_settings.m_lpfFIRlog2Decim != settings.m_lpfFIRlog2Decim))) || force)
{
plutoBox->setFIR(DevicePlutoSDRBox::USE_RX, (1<<settings.m_lpfFIRlog2Decim), settings.m_lpfFIRBW, settings.m_lpfFIRGain);
firFilterSet = true;
}
// Reset the filter if gain or bandwidth changes without change to any of the sample rates and not done at previous step
if (((settings.m_lpfFIRBW != m_settings.m_lpfFIRBW) ||
(settings.m_lpfFIRGain != m_settings.m_lpfFIRGain)) && !firFilterSet)
{
plutoBox->setFIR(DevicePlutoSDRBox::USE_RX, (1<<settings.m_lpfFIRlog2Decim), settings.m_lpfFIRBW, settings.m_lpfFIRGain);
firFilterSet = true;
}
if ((m_settings.m_lpfFIREnable != settings.m_lpfFIREnable) || force)
{
params.clear();
params.push_back(QString(tr("in_voltage_filter_fir_en=%1").arg(settings.m_lpfFIREnable ? 1 : 0)).toStdString());
plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); // eventually enable/disable FIR
}
plutoBox->setSampleRate(settings.m_devSampleRate); // set end point frequency first
plutoBox->setFIR(settings.m_lpfFIRlog2Decim, settings.m_lpfFIRBW, settings.m_lpfFIRGain);
plutoBox->setFIREnable(settings.m_lpfFIREnable); // eventually enable/disable FIR
plutoBox->getRxSampleRates(m_deviceSampleRates); // pick up possible new rates
qDebug() << "PlutoSDRInput::applySettings: BBPLL: " << m_deviceSampleRates.m_bbRate
@ -386,9 +363,7 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo
if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force)
{
int64_t newXO = plutoBox->getInitialXO() + ((plutoBox->getInitialXO()*settings.m_LOppmTenths) / 10000000L);
params.push_back(QString(tr("xo_correction=%1").arg(newXO)).toStdString());
paramsToSet = true;
plutoBox->setLOPPMTenths(settings.m_LOppmTenths);
}
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force)
@ -476,5 +451,26 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo
m_deviceAPI->getDeviceInputMessageQueue()->push(notif);
}
return false;
return true;
}
void PlutoSDRInput::getRSSI(std::string& rssiStr)
{
DevicePlutoSDRBox *plutoBox = m_deviceShared.m_deviceParams->getBox();
if (!plutoBox->getRSSI(rssiStr, 0)) {
rssiStr = "xxx dB";
}
}
bool PlutoSDRInput::fetchTemperature()
{
DevicePlutoSDRBox *plutoBox = m_deviceShared.m_deviceParams->getBox();
return plutoBox->fetchTemp();
}
float PlutoSDRInput::getTemperature()
{
DevicePlutoSDRBox *plutoBox = m_deviceShared.m_deviceParams->getBox();
return plutoBox->getTemp();
}

View File

@ -87,6 +87,9 @@ public:
virtual bool handleMessage(const Message& message);
uint32_t getADCSampleRate() const { return m_deviceSampleRates.m_addaConnvRate; }
void getRSSI(std::string& rssiStr);
bool fetchTemperature();
float getTemperature();
private:
DeviceSourceAPI *m_deviceAPI;

View File

@ -15,7 +15,12 @@
///////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <QDebug>
#include <QMessageBox>
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
#include "gui/glspectrum.h"
#include "device/devicesourceapi.h"
#include "plutosdr/deviceplutosdr.h"
#include "plutosdrinput.h"
@ -31,7 +36,9 @@ PlutoSDRInputGui::PlutoSDRInputGui(DeviceSourceAPI *deviceAPI, QWidget* parent)
m_sampleSource(NULL),
m_sampleRate(0),
m_deviceCenterFrequency(0),
m_lastEngineState((DSPDeviceSourceEngine::State)-1)
m_lastEngineState((DSPDeviceSourceEngine::State)-1),
m_doApplySettings(true),
m_statusCounter(0)
{
m_sampleSource = new PlutoSDRInput(m_deviceAPI);
m_deviceAPI->setSource(m_sampleSource);
@ -49,9 +56,12 @@ PlutoSDRInputGui::PlutoSDRInputGui(DeviceSourceAPI *deviceAPI, QWidget* parent)
ui->lpFIR->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
ui->lpFIR->setValueRange(5, 1U, 56000U); // will be dynamically recalculated
ui->hwDecimLabel->setText(QString::fromUtf8("H\u2193"));
ui->swDecimLabel->setText(QString::fromUtf8("S\u2193"));
blockApplySettings(true);
displaySettings();
blockApplySettings(false);
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
m_statusTimer.start(500);
@ -103,9 +113,10 @@ bool PlutoSDRInputGui::deserialize(const QByteArray& data)
{
if(m_settings.deserialize(data))
{
// displaySettings();
// m_forceSettings = true;
// sendSettings();
blockApplySettings(true);
displaySettings();
blockApplySettings(false);
sendSettings(true);
return true;
}
else
@ -115,7 +126,258 @@ bool PlutoSDRInputGui::deserialize(const QByteArray& data)
}
}
bool PlutoSDRInputGui::handleMessage(const Message& message)
bool PlutoSDRInputGui::handleMessage(const Message& message __attribute__((unused)))
{
return false;
}
void PlutoSDRInputGui::on_startStop_toggled(bool checked)
{
if (checked)
{
if (m_deviceAPI->initAcquisition())
{
m_deviceAPI->startAcquisition();
DSPEngine::instance()->startAudioOutput();
}
}
else
{
m_deviceAPI->stopAcquisition();
DSPEngine::instance()->stopAudioOutput();
}
}
void PlutoSDRInputGui::on_record_toggled(bool checked)
{
if (checked) {
ui->record->setStyleSheet("QToolButton { background-color : red; }");
} else {
ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
}
PlutoSDRInput::MsgFileRecord* message = PlutoSDRInput::MsgFileRecord::create(checked);
m_sampleSource->getInputMessageQueue()->push(message);
}
void PlutoSDRInputGui::on_centerFrequency_changed(quint64 value)
{
m_settings.m_centerFrequency = value * 1000;
sendSettings();
}
void PlutoSDRInputGui::on_loPPM_valueChanged(int value)
{
m_settings.m_LOppmTenths = value;
sendSettings();
}
void PlutoSDRInputGui::on_dcOffset_toggled(bool checked)
{
m_settings.m_dcBlock = checked;
sendSettings();
}
void PlutoSDRInputGui::on_iqImbalance_toggled(bool checked)
{
m_settings.m_iqCorrection = checked;
sendSettings();
}
void PlutoSDRInputGui::on_swDecim_currentIndexChanged(int index)
{
m_settings.m_log2Decim = index > 6 ? 6 : index;
sendSettings();
}
void PlutoSDRInputGui::on_fcPos_currentIndexChanged(int index)
{
m_settings.m_fcPos = (PlutoSDRInputSettings::fcPos_t) (index > 2 ? 2 : index);
sendSettings();
}
void PlutoSDRInputGui::on_sampleRate_changed(quint64 value)
{
m_settings.m_devSampleRate = value;
sendSettings();
}
void PlutoSDRInputGui::on_lpf_changed(quint64 value)
{
m_settings.m_lpfBW = value * 1000;
sendSettings();
}
void PlutoSDRInputGui::on_lpFIREnable_toggled(bool checked)
{
m_settings.m_lpfFIREnable = checked;
sendSettings();
}
void PlutoSDRInputGui::on_lpFIR_changed(quint64 value)
{
m_settings.m_lpfFIRBW = value * 1000;
sendSettings();
}
void PlutoSDRInputGui::on_lpFIRDecimation_currentIndexChanged(int index)
{
m_settings.m_lpfFIRlog2Decim = index > 2 ? 2 : index;
sendSettings();
}
void PlutoSDRInputGui::on_lpFIRGain_currentIndexChanged(int index)
{
m_settings.m_lpfFIRGain = 6*(index > 1 ? 1 : index) - 6;
sendSettings();
}
void PlutoSDRInputGui::on_gainMode_currentIndexChanged(int index)
{
m_settings.m_gainMode = (PlutoSDRInputSettings::GainMode) (index < PlutoSDRInputSettings::GAIN_END ? index : 0);
sendSettings();
}
void PlutoSDRInputGui::on_gain_valueChanged(int value)
{
m_settings.m_gain = value;
sendSettings();
}
void PlutoSDRInputGui::on_antenna_currentIndexChanged(int index)
{
m_settings.m_antennaPath = (PlutoSDRInputSettings::RFPath) (index < PlutoSDRInputSettings::RFPATH_END ? index : 0);
sendSettings();
}
void PlutoSDRInputGui::displaySettings()
{
ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
ui->sampleRate->setValue(m_settings.m_devSampleRate);
ui->dcOffset->setChecked(m_settings.m_dcBlock);
ui->iqImbalance->setChecked(m_settings.m_iqCorrection);
ui->swDecim->setCurrentIndex(m_settings.m_log2Decim);
ui->lpf->setValue(m_settings.m_lpfBW / 1000);
ui->lpFIREnable->setChecked(m_settings.m_lpfFIREnable);
ui->lpFIR->setValue(m_settings.m_lpfFIRBW / 1000);
ui->lpFIRDecimation->setCurrentIndex(m_settings.m_lpfFIRlog2Decim);
ui->lpFIRGain->setCurrentIndex((m_settings.m_lpfFIRGain + 6)/6);
ui->gainMode->setCurrentIndex((int) m_settings.m_gainMode);
ui->gain->setValue(m_settings.m_gain);
ui->gainText->setText(tr("%1").arg(m_settings.m_gain));
ui->antenna->setCurrentIndex((int) m_settings.m_antennaPath);
}
void PlutoSDRInputGui::sendSettings(bool forceSettings)
{
m_forceSettings = forceSettings;
if(!m_updateTimer.isActive()) { m_updateTimer.start(100); }
}
void PlutoSDRInputGui::updateHardware()
{
if (m_doApplySettings)
{
qDebug() << "PlutoSDRInputGui::updateHardware";
PlutoSDRInput::MsgConfigurePlutoSDR* message = PlutoSDRInput::MsgConfigurePlutoSDR::create(m_settings, m_forceSettings);
m_sampleSource->getInputMessageQueue()->push(message);
m_forceSettings = false;
m_updateTimer.stop();
}
}
void PlutoSDRInputGui::blockApplySettings(bool block)
{
m_doApplySettings = !block;
}
void PlutoSDRInputGui::updateStatus()
{
int state = m_deviceAPI->state();
if(m_lastEngineState != state)
{
switch(state)
{
case DSPDeviceSourceEngine::StNotStarted:
ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
break;
case DSPDeviceSourceEngine::StIdle:
ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
break;
case DSPDeviceSourceEngine::StRunning:
ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
break;
case DSPDeviceSourceEngine::StError:
ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
QMessageBox::information(this, tr("Message"), m_deviceAPI->errorMessage());
break;
default:
break;
}
m_lastEngineState = state;
}
if (m_statusCounter % 2 == 0) // 1s
{
uint32_t adcRate = ((PlutoSDRInput *) m_sampleSource)->getADCSampleRate();
if (adcRate < 100000000) {
ui->adcRateLabel->setText(tr("%1k").arg(QString::number(adcRate / 1000.0f, 'g', 5)));
} else {
ui->adcRateLabel->setText(tr("%1M").arg(QString::number(adcRate / 1000000.0f, 'g', 5)));
}
}
if (m_statusCounter % 4 == 0) // 2s
{
std::string rssiStr;
((PlutoSDRInput *) m_sampleSource)->getRSSI(rssiStr);
ui->rssiText->setText(QString::fromStdString(rssiStr));
}
if (m_statusCounter % 10 == 0) // 5s
{
if (m_deviceAPI->isBuddyLeader()) {
((PlutoSDRInput *) m_sampleSource)->fetchTemperature();
}
ui->temperatureText->setText(tr("%1C").arg(QString::number(((PlutoSDRInput *) m_sampleSource)->getTemperature(), 'f', 0)));
}
m_statusCounter++;
}
void PlutoSDRInputGui::handleDSPMessages()
{
Message* message;
while ((message = m_deviceAPI->getDeviceOutputMessageQueue()->pop()) != 0)
{
if (DSPSignalNotification::match(*message))
{
qDebug("LimeSDRInputGUI::handleMessagesToGUI: message: %s", message->getIdentifier());
DSPSignalNotification* notif = (DSPSignalNotification*) message;
m_sampleRate = notif->getSampleRate();
m_deviceCenterFrequency = notif->getCenterFrequency();
qDebug("LimeSDRInputGUI::handleMessagesToGUI: SampleRate: %d, CenterFrequency: %llu", notif->getSampleRate(), notif->getCenterFrequency());
updateSampleRateAndFrequency();
delete message;
}
}
}
void PlutoSDRInputGui::updateSampleRateAndFrequency()
{
m_deviceAPI->getSpectrum()->setSampleRate(m_sampleRate);
m_deviceAPI->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency);
ui->deviceRateLabel->setText(tr("%1k").arg(QString::number(m_sampleRate / 1000.0f, 'g', 5)));
}

View File

@ -60,6 +60,35 @@ private:
int m_sampleRate;
quint64 m_deviceCenterFrequency; //!< Center frequency in device
int m_lastEngineState;
bool m_doApplySettings;
uint32_t m_statusCounter;
void displaySettings();
void sendSettings(bool forceSettings = false);
void blockApplySettings(bool block);
void updateSampleRateAndFrequency();
private slots:
void on_startStop_toggled(bool checked);
void on_record_toggled(bool checked);
void on_centerFrequency_changed(quint64 value);
void on_loPPM_valueChanged(int value);
void on_dcOffset_toggled(bool checked);
void on_iqImbalance_toggled(bool checked);
void on_swDecim_currentIndexChanged(int index);
void on_fcPos_currentIndexChanged(int index);
void on_sampleRate_changed(quint64 value);
void on_lpf_changed(quint64 value);
void on_lpFIREnable_toggled(bool checked);
void on_lpFIR_changed(quint64 value);
void on_lpFIRDecimation_currentIndexChanged(int index);
void on_lpFIRGain_currentIndexChanged(int index);
void on_gainMode_currentIndexChanged(int index);
void on_gain_valueChanged(int value);
void on_antenna_currentIndexChanged(int index);
void updateHardware();
void updateStatus();
void handleDSPMessages();
};
#endif /* PLUGINS_SAMPLESOURCE_PLUTOSDRINPUT_PLUTOSDRINPUTGUI_H_ */

View File

@ -301,42 +301,6 @@
<property name="topMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="hwDecimLabel">
<property name="text">
<string>Hw</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="hwDecim">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Hardware decimation governor</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>3</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="swDecimLabel">
<property name="text">
@ -613,14 +577,14 @@
</widget>
</item>
<item>
<widget class="QLabel" name="lpfUnits_2">
<widget class="QLabel" name="lpfFIRUnits">
<property name="text">
<string>kHz</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="firDecimation">
<widget class="QComboBox" name="lpFIRDecimation">
<property name="maximumSize">
<size>
<width>50</width>
@ -648,7 +612,7 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="firGain">
<widget class="QComboBox" name="lpFIRGain">
<property name="maximumSize">
<size>
<width>50</width>
@ -658,11 +622,6 @@
<property name="toolTip">
<string>FIR gain (dB)</string>
</property>
<item>
<property name="text">
<string>-12</string>
</property>
</item>
<item>
<property name="text">
<string>-6</string>
@ -673,11 +632,6 @@
<string>0</string>
</property>
</item>
<item>
<property name="text">
<string>+6</string>
</property>
</item>
</widget>
</item>
<item>
@ -704,7 +658,7 @@
<number>2</number>
</property>
<item>
<widget class="QComboBox" name="gainCtlMode">
<widget class="QComboBox" name="gainMode">
<property name="maximumSize">
<size>
<width>54</width>
@ -922,8 +876,17 @@
</item>
<item>
<widget class="QLabel" name="rssiText">
<property name="minimumSize">
<size>
<width>65</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>-100.0 dB</string>
<string>100.00 dB</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>

View File

@ -31,13 +31,12 @@ void PlutoSDRInputSettings::resetToDefaults()
m_fcPos = FC_POS_CENTER;
m_LOppmTenths = 0;
m_log2Decim = 0;
m_devSampleRate = 1536 * 1000;
m_rateGovernor = RATEGOV_NORMAL;
m_devSampleRate = 2500 * 1000;
m_dcBlock = false;
m_iqCorrection = false;
m_lpfBW = 1500000.0f;
m_lpfFIREnable = false;
m_lpfFIRBW = 500000.0f;
m_lpfFIRBW = 500000U;
m_lpfFIRlog2Decim = 0;
m_gain = 40;
m_antennaPath = RFPATH_A_BAL;
@ -53,12 +52,11 @@ QByteArray PlutoSDRInputSettings::serialize() const
s.writeU32(3, m_lpfFIRlog2Decim);
s.writeU32(4, m_log2Decim);
s.writeS32(5, m_fcPos);
s.writeS32(6, m_rateGovernor);
s.writeBool(7, m_dcBlock);
s.writeBool(8, m_iqCorrection);
s.writeFloat(9, m_lpfBW);
s.writeBool(10, m_lpfFIREnable);
s.writeFloat(11, m_lpfFIRBW);
s.writeU32(11, m_lpfFIRBW);
s.writeU64(12, m_devSampleRate);
s.writeU32(13, m_gain);
s.writeS32(14, (int) m_antennaPath);
@ -97,17 +95,11 @@ bool PlutoSDRInputSettings::deserialize(const QByteArray& data)
} else {
m_fcPos = (fcPos_t) intval;
}
d.readS32(6, &intval, 0);
if ((intval >= 0) && (intval < (int) RATEGOV_END)) {
m_rateGovernor = (RateGovernor) intval;
} else {
m_rateGovernor = RATEGOV_NORMAL;
}
d.readBool(7, &m_dcBlock, false);
d.readBool(8, &m_iqCorrection, false);
d.readFloat(9, &m_lpfBW, 1500000.0f);
d.readBool(10, &m_lpfFIREnable, false);
d.readFloat(11, &m_lpfFIRBW, 500000.0f);
d.readU32(11, &m_lpfFIRBW, 500000U);
d.readU64(12, &m_devSampleRate, 1536000U);
d.readU32(13, &m_gain, 40);
d.readS32(14, &intval, 0);
@ -132,22 +124,6 @@ bool PlutoSDRInputSettings::deserialize(const QByteArray& data)
}
}
void PlutoSDRInputSettings::translateGovernor(RateGovernor gov, QString& s)
{
switch(gov)
{
case RATEGOV_NORMAL:
s = "normal";
break;
case RATEGOV_HIGHOSR:
s = "highest_osr";
break;
default:
s = "highest_osr";
break;
}
}
void PlutoSDRInputSettings::translateRFPath(RFPath path, QString& s)
{
switch(path)

View File

@ -52,27 +52,21 @@ struct PlutoSDRInputSettings {
GAIN_END
} GainMode;
typedef enum {
RATEGOV_NORMAL,
RATEGOV_HIGHOSR,
RATEGOV_END
} RateGovernor;
// global settings to be saved
quint64 m_centerFrequency;
quint64 m_devSampleRate;
RateGovernor m_rateGovernor;
// channel settings
// common device settings
quint64 m_devSampleRate; //!< Host interface sample rate
qint32 m_LOppmTenths; //!< XO correction
bool m_lpfFIREnable; //!< enable digital lowpass FIR filter
quint32 m_lpfFIRBW; //!< digital lowpass FIR filter bandwidth (Hz)
quint32 m_lpfFIRlog2Decim; //!< digital lowpass FIR filter log2 of decimation factor (0..2)
int m_lpfFIRGain; //!< digital lowpass FIR filter gain (dB)
// individual channel settings
fcPos_t m_fcPos;
qint32 m_LOppmTenths;
bool m_dcBlock;
bool m_iqCorrection;
quint32 m_log2Decim;
float m_lpfBW; //!< analog lowpass filter bandwidth (Hz)
bool m_lpfFIREnable; //!< enable digital lowpass FIR filter
float m_lpfFIRBW; //!< digital lowpass FIR filter bandwidth (Hz)
quint32 m_lpfFIRlog2Decim; //!< digital lowpass FIR filter log2 of decimation factor (0..2)
int m_lpfFIRGain; //!< digital lowpass FIR filter gain (dB)
uint32_t m_gain; //!< "hardware" gain
RFPath m_antennaPath;
GainMode m_gainMode;
@ -82,7 +76,6 @@ struct PlutoSDRInputSettings {
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
static void translateGovernor(RateGovernor gov, QString& s);
static void translateRFPath(RFPath path, QString& s);
static void translateGainMode(GainMode mod, QString& s);
};