1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-06-01 21:54:55 -04:00

Import USRP support.

Add LO offset support.
Only set tx/rx_bandwidth after getting tx stream, to reduce TX LO leakage for <10MHz bandwidths.
Check for reference and LO lock before getting streams.
This commit is contained in:
Jon Beniston
2020-10-25 11:57:48 +00:00
parent 209be94947
commit d8ae6fc765
17 changed files with 299 additions and 70 deletions
+67 -38
View File
@@ -316,25 +316,41 @@ bool USRPInput::acquireChannel()
suspendRxBuddies();
suspendTxBuddies();
try
if (m_streamId == nullptr)
{
// set up the stream
std::string cpu_format("sc16");
std::string wire_format("sc16");
std::vector<size_t> channel_nums;
channel_nums.push_back(m_deviceShared.m_channel);
try
{
uhd::usrp::multi_usrp::sptr usrp = m_deviceShared.m_deviceParams->getDevice();
uhd::stream_args_t stream_args(cpu_format, wire_format);
stream_args.channels = channel_nums;
// Apply settings before creating stream
// However, don't set LPF to <10MHz at this stage, otherwise there is massive TX LO leakage
applySettings(m_settings, true, true);
usrp->set_rx_bandwidth(56000000, m_deviceShared.m_channel);
m_streamId = m_deviceShared.m_deviceParams->getDevice()->get_rx_stream(stream_args);
// set up the stream
std::string cpu_format("sc16");
std::string wire_format("sc16");
std::vector<size_t> channel_nums;
channel_nums.push_back(m_deviceShared.m_channel);
// Match our receive buffer size to what UHD uses
m_bufSamples = m_streamId->get_max_num_samps();
}
catch (std::exception& e)
{
qDebug() << "USRPInput::acquireChannel: exception: " << e.what();
uhd::stream_args_t stream_args(cpu_format, wire_format);
stream_args.channels = channel_nums;
m_streamId = m_deviceShared.m_deviceParams->getDevice()->get_rx_stream(stream_args);
// Match our receive buffer size to what UHD uses
m_bufSamples = m_streamId->get_max_num_samps();
// Wait for reference and LO to lock
DeviceUSRP::waitForLock(usrp, m_settings.m_clockSource, m_deviceShared.m_channel);
// Now we can set desired bandwidth
usrp->set_rx_bandwidth(m_settings.m_lpfBW, m_deviceShared.m_channel);
}
catch (std::exception& e)
{
qDebug() << "USRPInput::acquireChannel: exception: " << e.what();
}
}
resumeTxBuddies();
@@ -350,7 +366,7 @@ void USRPInput::releaseChannel()
suspendRxBuddies();
suspendTxBuddies();
// destroy the stream - FIXME: Better way to do this?
// destroy the stream
m_streamId = nullptr;
resumeTxBuddies();
@@ -363,7 +379,7 @@ void USRPInput::releaseChannel()
void USRPInput::init()
{
applySettings(m_settings, true);
applySettings(m_settings, false, true);
}
bool USRPInput::start()
@@ -384,8 +400,6 @@ bool USRPInput::start()
m_usrpInputThread = new USRPInputThread(m_streamId, m_bufSamples, &m_sampleFifo);
qDebug("USRPInput::start: thread created");
applySettings(m_settings, true);
m_usrpInputThread->setLog2Decimation(m_settings.m_log2SoftDecim);
m_usrpInputThread->startWork();
@@ -521,7 +535,7 @@ bool USRPInput::handleMessage(const Message& message)
MsgConfigureUSRP& conf = (MsgConfigureUSRP&) message;
qDebug() << "USRPInput::handleMessage: MsgConfigureUSRP";
if (!applySettings(conf.getSettings(), conf.getForce()))
if (!applySettings(conf.getSettings(), false, conf.getForce()))
{
qDebug("USRPInput::handleMessage config error");
}
@@ -536,6 +550,7 @@ bool USRPInput::handleMessage(const Message& message)
{
m_settings.m_devSampleRate = report.getDevSampleRate();
m_settings.m_centerFrequency = report.getCenterFrequency();
m_settings.m_loOffset = report.getLOOffset();
}
else if (m_running)
{
@@ -556,7 +571,7 @@ bool USRPInput::handleMessage(const Message& message)
if (getMessageQueueToGUI())
{
DeviceUSRPShared::MsgReportBuddyChange *reportToGUI = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, true);
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true);
getMessageQueueToGUI()->push(reportToGUI);
}
@@ -633,7 +648,7 @@ bool USRPInput::handleMessage(const Message& message)
}
}
bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
bool USRPInput::applySettings(const USRPInputSettings& settings, bool preGetStream, bool force)
{
bool forwardChangeOwnDSP = false;
bool forwardChangeRxDSP = false;
@@ -655,7 +670,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
{
reverseAPIKeys.append("clockSource");
if (m_deviceShared.m_deviceParams->getDevice())
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
{
try
{
@@ -686,7 +701,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
reverseAPIKeys.append("devSampleRate");
forwardChangeAllDSP = true;
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
{
m_deviceShared.m_deviceParams->getDevice()->set_rx_rate(settings.m_devSampleRate, m_deviceShared.m_channel);
double actualSampleRate = m_deviceShared.m_deviceParams->getDevice()->get_rx_rate(m_deviceShared.m_channel);
@@ -698,6 +713,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
}
if ((m_settings.m_centerFrequency != settings.m_centerFrequency)
|| (m_settings.m_loOffset != settings.m_loOffset)
|| (m_settings.m_transverterMode != settings.m_transverterMode)
|| (m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency)
|| force)
@@ -707,26 +723,34 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
reverseAPIKeys.append("transverterDeltaFrequency");
forwardChangeRxDSP = true;
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
{
uhd::tune_request_t tune_request(deviceCenterFrequency);
m_deviceShared.m_deviceParams->getDevice()->set_rx_freq(tune_request, m_deviceShared.m_channel);
if (settings.m_loOffset != 0)
{
uhd::tune_request_t tune_request(deviceCenterFrequency, settings.m_loOffset);
m_deviceShared.m_deviceParams->getDevice()->set_rx_freq(tune_request, m_deviceShared.m_channel);
}
else
{
uhd::tune_request_t tune_request(deviceCenterFrequency);
m_deviceShared.m_deviceParams->getDevice()->set_rx_freq(tune_request, m_deviceShared.m_channel);
}
m_deviceShared.m_centerFrequency = deviceCenterFrequency; // for buddies
qDebug("USRPInput::applySettings: frequency set to %lld", deviceCenterFrequency);
qDebug("USRPInput::applySettings: frequency set to %lld with LO offset %d", deviceCenterFrequency, settings.m_loOffset);
}
}
if ((m_settings.m_dcBlock != settings.m_dcBlock) || force)
{
reverseAPIKeys.append("dcBlock");
if (m_deviceShared.m_deviceParams->getDevice())
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
m_deviceShared.m_deviceParams->getDevice()->set_rx_dc_offset(settings.m_dcBlock, m_deviceShared.m_channel);
}
if ((m_settings.m_iqCorrection != settings.m_iqCorrection) || force)
{
reverseAPIKeys.append("iqCorrection");
if (m_deviceShared.m_deviceParams->getDevice())
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
m_deviceShared.m_deviceParams->getDevice()->set_rx_iq_balance(settings.m_iqCorrection, m_deviceShared.m_channel);
}
@@ -734,7 +758,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
{
reverseAPIKeys.append("gainMode");
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
{
if (settings.m_gainMode == USRPInputSettings::GAIN_AUTO)
{
@@ -754,7 +778,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
{
reverseAPIKeys.append("gain");
if ((settings.m_gainMode != USRPInputSettings::GAIN_AUTO) && m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
if ((settings.m_gainMode != USRPInputSettings::GAIN_AUTO) && m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
{
m_deviceShared.m_deviceParams->getDevice()->set_rx_gain(settings.m_gain, m_deviceShared.m_channel);
qDebug() << "USRPInput::applySettings: Gain set to " << settings.m_gain << " for channel " << m_deviceShared.m_channel;
@@ -764,8 +788,13 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
if ((m_settings.m_lpfBW != settings.m_lpfBW) || force)
{
reverseAPIKeys.append("lpfBW");
m_deviceShared.m_deviceParams->getDevice()->set_rx_bandwidth(settings.m_lpfBW, m_deviceShared.m_channel);
qDebug("USRPOutput::applySettings: LPF BW: %f for channel %d", settings.m_lpfBW, m_deviceShared.m_channel);
// Don't set bandwidth before get_rx_stream (See above)
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
{
m_deviceShared.m_deviceParams->getDevice()->set_rx_bandwidth(settings.m_lpfBW, m_deviceShared.m_channel);
qDebug("USRPInput::applySettings: LPF BW: %f for channel %d", settings.m_lpfBW, m_deviceShared.m_channel);
}
}
if ((m_settings.m_log2SoftDecim != settings.m_log2SoftDecim) || force)
@@ -785,7 +814,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
{
reverseAPIKeys.append("antennaPath");
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
{
m_deviceShared.m_deviceParams->getDevice()->set_rx_antenna(settings.m_antennaPath.toStdString(), m_deviceShared.m_channel);
qDebug("USRPInput::applySettings: set antenna path to %s on channel %d", qPrintable(settings.m_antennaPath), m_deviceShared.m_channel);
@@ -835,7 +864,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
for (; itSource != sourceBuddies.end(); ++itSource)
{
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, true);
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true);
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
}
@@ -846,7 +875,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
for (; itSink != sinkBuddies.end(); ++itSink)
{
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, true);
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true);
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
}
}
@@ -867,7 +896,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
for (; itSource != sourceBuddies.end(); ++itSource)
{
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, true);
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true);
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
}
}
+1 -1
View File
@@ -239,7 +239,7 @@ private:
void resumeRxBuddies();
void suspendTxBuddies();
void resumeTxBuddies();
bool applySettings(const USRPInputSettings& settings, bool force = false);
bool applySettings(const USRPInputSettings& settings, bool preGetStream, bool force = false);
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const USRPInputSettings& settings, bool force);
void webapiReverseSendStartStop(bool start);
@@ -61,6 +61,9 @@ USRPInputGUI::USRPInputGUI(DeviceUISet *deviceUISet, QWidget* parent) :
ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
ui->sampleRate->setValueRange(8, (uint32_t) minF, (uint32_t) maxF);
ui->loOffset->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
ui->loOffset->setValueRange(false, 5, (int32_t)-maxF/2/1000, (int32_t)maxF/2/1000); // LO offset shouldn't be greater than half the sample rate
m_usrpInput->getLPRange(minF, maxF);
ui->lpf->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
ui->lpf->setValueRange(5, (minF/1000)+1, maxF/1000);
@@ -164,6 +167,7 @@ bool USRPInputGUI::handleMessage(const Message& message)
if (report.getRxElseTx()) {
m_settings.m_centerFrequency = report.getCenterFrequency();
m_settings.m_loOffset = report.getLOOffset();
}
blockApplySettings(true);
@@ -174,7 +178,7 @@ bool USRPInputGUI::handleMessage(const Message& message)
}
else if (DeviceUSRPShared::MsgReportClockSourceChange::match(message))
{
qDebug("USRPInputGUI::handleMessage MsgReportClockSourceChange");
qDebug("USRPInputGUI::handleMessage MsgReportClockSourceChange");
DeviceUSRPShared::MsgReportClockSourceChange& report = (DeviceUSRPShared::MsgReportClockSourceChange&) message;
m_settings.m_clockSource = report.getClockSource();
@@ -289,6 +293,8 @@ void USRPInputGUI::updateSampleRate()
} else {
ui->sampleRateLabel->setText(tr("%1M").arg(QString::number(sr / 1000000.0f, 'g', 5)));
}
// LO offset shouldn't be greater than half the sample rate
ui->loOffset->setValueRange(false, 5, -(int32_t)sr/2/1000, (int32_t)sr/2/1000);
}
void USRPInputGUI::updateSampleRateAndFrequency()
@@ -350,6 +356,7 @@ void USRPInputGUI::displaySettings()
updateSampleRate();
ui->lpf->setValue(m_settings.m_lpfBW / 1000);
ui->loOffset->setValue(m_settings.m_loOffset / 1000);
ui->gain->setValue(m_settings.m_gain);
ui->gainText->setText(tr("%1").arg(m_settings.m_gain));
@@ -527,6 +534,12 @@ void USRPInputGUI::on_lpf_changed(quint64 value)
sendSettings();
}
void USRPInputGUI::on_loOffset_changed(qint64 value)
{
m_settings.m_loOffset = value * 1000;
sendSettings();
}
void USRPInputGUI::on_gainMode_currentIndexChanged(int index)
{
m_settings.m_gainMode = (USRPInputSettings::GainMode) index;
@@ -89,6 +89,7 @@ private slots:
void on_sampleRate_changed(quint64 value);
void on_swDecim_currentIndexChanged(int index);
void on_lpf_changed(quint64 value);
void on_loOffset_changed(qint64 value);
void on_gainMode_currentIndexChanged(int index);
void on_gain_valueChanged(int value);
void on_antenna_currentIndexChanged(int index);
@@ -626,6 +626,57 @@
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="loOffsetLabel">
<property name="text">
<string>LO</string>
</property>
</widget>
</item>
<item>
<widget class="ValueDialZ" name="loOffset" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>12</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="toolTip">
<string>LO offset (kHz)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="loOffsetUnits">
<property name="text">
<string>kHz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -753,6 +804,12 @@
<extends>QPushButton</extends>
<header>gui/transverterbutton.h</header>
</customwidget>
<customwidget>
<class>ValueDialZ</class>
<extends>QWidget</extends>
<header>gui/valuedialz.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>
@@ -28,10 +28,11 @@ void USRPInputSettings::resetToDefaults()
{
m_centerFrequency = 435000*1000;
m_devSampleRate = 3000000;
m_loOffset = 0;
m_dcBlock = false;
m_iqCorrection = false;
m_log2SoftDecim = 0;
m_lpfBW = 5.5e6f;
m_lpfBW = 10e6f;
m_gain = 50;
m_antennaPath = "TX/RX";
m_gainMode = GAIN_AUTO;
@@ -63,6 +64,7 @@ QByteArray USRPInputSettings::serialize() const
s.writeString(13, m_reverseAPIAddress);
s.writeU32(14, m_reverseAPIPort);
s.writeU32(15, m_reverseAPIDeviceIndex);
s.writeS32(16, m_loOffset);
return s.final();
}
@@ -105,6 +107,7 @@ bool USRPInputSettings::deserialize(const QByteArray& data)
d.readU32(15, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
d.readS32(16, &m_loOffset, 0);
return true;
}
@@ -37,6 +37,7 @@ struct USRPInputSettings
// global settings to be saved
uint64_t m_centerFrequency;
int m_devSampleRate;
int m_loOffset;
// channel settings
bool m_dcBlock;
bool m_iqCorrection;