diff --git a/devices/plutosdr/deviceplutosdrbox.cpp b/devices/plutosdr/deviceplutosdrbox.cpp index 98e4bcf55..48065b571 100644 --- a/devices/plutosdr/deviceplutosdrbox.cpp +++ b/devices/plutosdr/deviceplutosdrbox.cpp @@ -29,13 +29,18 @@ DevicePlutoSDRBox::DevicePlutoSDRBox(const std::string& uri) : m_chnRx0(0), m_chnTx0(0), m_rxBuf(0), - m_txBuf(0) + m_txBuf(0), + m_xoInitial(0) { m_ctx = iio_create_context_from_uri(uri.c_str()); m_devPhy = iio_context_find_device(m_ctx, "ad9361-phy"); m_devRx = iio_context_find_device(m_ctx, "cf-ad9361-lpc"); m_devTx = iio_context_find_device(m_ctx, "cf-ad9361-dds-core-lpc"); m_valid = m_ctx && m_devPhy && m_devRx && m_devTx; + + if (m_valid) { + getXO(); + } } DevicePlutoSDRBox::~DevicePlutoSDRBox() @@ -458,4 +463,18 @@ void DevicePlutoSDRBox::formatFIRCoefficients(std::ostringstream& ostr, uint32_t } } +void DevicePlutoSDRBox::getXO() +{ + std::string valueStr; + get_param(DEVICE_PHY, "xo_correction", valueStr); + try + { + m_xoInitial = boost::lexical_cast(valueStr); + } + catch (const boost::bad_lexical_cast &e) + { + qWarning("DevicePlutoSDRBox::getXO: cannot get initial XO correction"); + } +} + diff --git a/devices/plutosdr/deviceplutosdrbox.h b/devices/plutosdr/deviceplutosdrbox.h index e5fd8132c..c0938ac38 100644 --- a/devices/plutosdr/deviceplutosdrbox.h +++ b/devices/plutosdr/deviceplutosdrbox.h @@ -81,6 +81,7 @@ public: 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; } private: struct iio_context *m_ctx; @@ -92,11 +93,13 @@ private: struct iio_buffer *m_rxBuf; struct iio_buffer *m_txBuf; bool m_valid; + int64_t m_xoInitial; 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 formatFIRCoefficients(std::ostringstream& str, uint32_t nbTaps, double normalizedBW); + void getXO(); }; #endif /* DEVICES_PLUTOSDR_DEVICEPLUTOSDRBOX_H_ */ diff --git a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp index 67ea20e73..c8520e4b7 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp @@ -247,7 +247,6 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo bool suspendOwnThread = false; bool ownThreadWasRunning = false; bool suspendAllOtherThreads = false; // All others means Tx in fact - bool doCalibration = false; bool firFilterSet = false; DevicePlutoSDRBox *plutoBox = m_deviceShared.m_deviceParams->getBox(); @@ -302,6 +301,12 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo // TODO: apply settings (all cases) + if ((m_settings.m_dcBlock != settings.m_dcBlock) || + (m_settings.m_iqCorrection != settings.m_iqCorrection) || force) + { + m_deviceAPI->configureCorrections(settings.m_dcBlock, m_settings.m_iqCorrection); + } + // Change affecting device sample rate chain potentially affecting other buddies device/host sample rate if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || (m_settings.m_rateGovernor != settings.m_rateGovernor) || @@ -361,29 +366,72 @@ bool PlutoSDRInput::applySettings(const PlutoSDRInputSettings& settings, bool fo if (m_plutoSDRInputThread != 0) { m_plutoSDRInputThread->setLog2Decimation(settings.m_log2Decim); - qDebug() << "PlutoSDRInput::applySettings: set soft decimation to " << (1<setFcPos(settings.m_fcPos); + qDebug() << "PlutoSDRInput::applySettings: set fcPos to " << (1<getInitialXO() + ((plutoBox->getInitialXO()*settings.m_LOppmTenths) / 10000000L); + std::vector params; + params.push_back(QString(tr("xo_correction=%1").arg(newXO)).toStdString()); + plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); + } + if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) { std::vector params; - params.push_back(QString(tr("in_voltage_sampling_frequency=%1").arg(settings.m_centerFrequency)).toStdString()); + params.push_back(QString(tr("out_altvoltage0_RX_LO_frequency=%1").arg(settings.m_centerFrequency)).toStdString()); plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); forwardChangeOwnDSP = true; } - m_settings = settings; - - // TODO: calibration - if (doCalibration) + if ((m_settings.m_lpfBW != settings.m_lpfBW) || force) { - qDebug("PlutoSDRInput::applySettings: doCalibration"); + std::vector params; + params.push_back(QString(tr("in_voltage_rf_bandwidth=%1").arg(settings.m_lpfBW)).toStdString()); + plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); } + if ((m_settings.m_antennaPath != settings.m_antennaPath) || force) + { + std::vector params; + QString rfPortStr; + PlutoSDRInputSettings::translateRFPath(settings.m_antennaPath, rfPortStr); + params.push_back(QString(tr("in_voltage0_rf_port_select=%1").arg(rfPortStr)).toStdString()); + plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); + } + + if ((m_settings.m_gainMode != settings.m_gainMode) || force) + { + std::vector params; + QString gainModeStr; + PlutoSDRInputSettings::translateGainMode(settings.m_gainMode, gainModeStr); + params.push_back(QString(tr("in_voltage0_gain_control_mode=%1").arg(gainModeStr)).toStdString()); + plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); + } + + if ((m_settings.m_gain != settings.m_gain) || force) + { + std::vector params; + params.push_back(QString(tr("in_voltage0_hardwaregain=%1").arg(settings.m_gain)).toStdString()); + plutoBox->set_params(DevicePlutoSDRBox::DEVICE_PHY, params); + } + + m_settings = settings; + if (suspendAllOtherThreads) { const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputsettings.cpp b/plugins/samplesource/plutosdrinput/plutosdrinputsettings.cpp index d7545a0df..24de677e6 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputsettings.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinputsettings.cpp @@ -147,3 +147,71 @@ void PlutoSDRInputSettings::translateGovernor(RateGovernor gov, QString& s) break; } } + +void PlutoSDRInputSettings::translateRFPath(RFPath path, QString& s) +{ + switch(path) + { + case RFPATH_A_BAL: + s = "A_BALANCED"; + break; + case RFPATH_B_BAL: + s = "B_BALANCED"; + break; + case RFPATH_C_BAL: + s = "C_BALANCED"; + break; + case RFPATH_A_NEG: + s = "A_N"; + break; + case RFPATH_A_POS: + s = "A_P"; + break; + case RFPATH_B_NEG: + s = "B_N"; + break; + case RFPATH_B_POS: + s = "B_P"; + break; + case RFPATH_C_NEG: + s = "C_N"; + break; + case RFPATH_C_POS: + s = "C_P"; + break; + case RFPATH_TX1MON: + s = "TX_MONITOR1"; + break; + case RFPATH_TX2MON: + s = "TX_MONITOR2"; + break; + case RFPATH_TX3MON: + s = "TX_MONITOR3"; + break; + default: + s = "A_BALANCED"; + break; + } +} + +void PlutoSDRInputSettings::translateGainMode(GainMode mode, QString& s) +{ + switch(mode) + { + case GAIN_MANUAL: + s = "manual"; + break; + case GAIN_AGC_SLOW: + s = "slow_attack"; + break; + case GAIN_AGC_FAST: + s = "fast_attack"; + break; + case GAIN_HYBRID: + s = "hybrid"; + break; + default: + s = "manual"; + break; + } +} diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputsettings.h b/plugins/samplesource/plutosdrinput/plutosdrinputsettings.h index d0a8c92c2..7a0f6ba02 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputsettings.h +++ b/plugins/samplesource/plutosdrinput/plutosdrinputsettings.h @@ -83,6 +83,8 @@ struct PlutoSDRInputSettings { 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); }; #endif /* _PLUTOSDR_PLUTOSDRINPUTSETTINGS_H_ */