1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 01:55:48 -05:00

Add master clock rate display to GUI.

Calculate full range of sample rates supported, by varying master clock.
Check if requested sample rate can be met.
This commit is contained in:
Jon Beniston 2020-10-26 14:39:12 +00:00
parent 636c014427
commit 2400c4643c
14 changed files with 198 additions and 85 deletions

View File

@ -52,7 +52,7 @@ void DeviceUSRP::enumOriginDevices(const QString& hardwareId, PluginInterface::O
qDebug() << "DeviceUSRP::enumOriginDevices: found USRP device " << displayedName; qDebug() << "DeviceUSRP::enumOriginDevices: found USRP device " << displayedName;
DeviceUSRPParams usrpParams; DeviceUSRPParams usrpParams;
usrpParams.open(id.toStdString().c_str()); usrpParams.open(id.toStdString().c_str(), true);
usrpParams.close(); usrpParams.close();
originDevices.append(PluginInterface::OriginDevice( originDevices.append(PluginInterface::OriginDevice(

View File

@ -19,7 +19,7 @@
#include <QDebug> #include <QDebug>
#include "deviceusrpparam.h" #include "deviceusrpparam.h"
bool DeviceUSRPParams::open(const char *deviceStr) bool DeviceUSRPParams::open(const char *deviceStr, bool channelNumOnly)
{ {
qDebug("DeviceUSRPParams::open: %s", (const char *) deviceStr); qDebug("DeviceUSRPParams::open: %s", (const char *) deviceStr);
@ -32,37 +32,71 @@ bool DeviceUSRPParams::open(const char *deviceStr)
m_nbRxChannels = m_dev->get_rx_num_channels(); m_nbRxChannels = m_dev->get_rx_num_channels();
m_nbTxChannels = m_dev->get_tx_num_channels(); m_nbTxChannels = m_dev->get_tx_num_channels();
m_lpfRangeRx = m_dev->get_rx_bandwidth_range(); // Speed up program initialisation, by not getting all properties
m_lpfRangeTx = m_dev->get_tx_bandwidth_range(); // If we could find out number of channles without ::make ing the device
// that would be even better
if (!channelNumOnly)
{
m_lpfRangeRx = m_dev->get_rx_bandwidth_range();
m_lpfRangeTx = m_dev->get_tx_bandwidth_range();
m_loRangeRx = m_dev->get_fe_rx_freq_range(); m_loRangeRx = m_dev->get_fe_rx_freq_range();
m_loRangeTx = m_dev->get_fe_tx_freq_range(); m_loRangeTx = m_dev->get_fe_tx_freq_range();
m_srRangeRx = m_dev->get_rx_rates(); // For some devices (B210), rx/tx_rates vary with master_clock_rate
m_srRangeTx = m_dev->get_tx_rates(); // Note master_clock_rate is rate between FPGA and RFIC
// tx/rx_rate is rate between PC and FPGA
uhd::meta_range_t clockRange = m_dev->get_master_clock_rate_range();
if (clockRange.start() == clockRange.stop())
{
m_srRangeRx = m_dev->get_rx_rates();
m_srRangeTx = m_dev->get_tx_rates();
}
else
{
// Find max and min sample rate, for max and min master clock rates
m_dev->set_master_clock_rate(clockRange.start());
uhd::meta_range_t rxLow = m_dev->get_rx_rates();
uhd::meta_range_t txLow = m_dev->get_tx_rates();
m_gainRangeRx = m_dev->get_rx_gain_range(); m_dev->set_master_clock_rate(clockRange.stop());
m_gainRangeTx = m_dev->get_tx_gain_range(); uhd::meta_range_t rxHigh = m_dev->get_rx_rates();
uhd::meta_range_t txHigh = m_dev->get_tx_rates();
std::vector<std::string> txAntennas = m_dev->get_tx_antennas(); m_srRangeRx = uhd::meta_range_t(std::min(rxLow.start(), rxHigh.start()), std::max(rxLow.stop(), rxHigh.stop()));
m_txAntennas.reserve(txAntennas.size()); m_srRangeTx = uhd::meta_range_t(std::min(txLow.start(), txHigh.start()), std::max(txLow.stop(), txHigh.stop()));
for(size_t i = 0, l = txAntennas.size(); i < l; ++i)
m_txAntennas << QString::fromStdString(txAntennas[i]);
std::vector<std::string> rxAntennas = m_dev->get_rx_antennas(); // Need to restore automatic clock rate
m_rxAntennas.reserve(rxAntennas.size()); uhd::property_tree::sptr properties = m_dev->get_tree();
for(size_t i = 0, l = rxAntennas.size(); i < l; ++i) if (properties->exists("/mboards/0/auto_tick_rate"))
m_rxAntennas << QString::fromStdString(rxAntennas[i]); {
properties->access<bool>("/mboards/0/auto_tick_rate").set(true);
}
}
std::vector<std::string> rxGainNames = m_dev->get_rx_gain_names(); m_gainRangeRx = m_dev->get_rx_gain_range();
m_rxGainNames.reserve(rxGainNames.size()); m_gainRangeTx = m_dev->get_tx_gain_range();
for(size_t i = 0, l = rxGainNames.size(); i < l; ++i)
m_rxGainNames << QString::fromStdString(rxGainNames[i]);
std::vector<std::string> clockSources = m_dev->get_clock_sources(0); std::vector<std::string> txAntennas = m_dev->get_tx_antennas();
m_clockSources.reserve(clockSources.size()); m_txAntennas.reserve(txAntennas.size());
for(size_t i = 0, l = clockSources.size(); i < l; ++i) for(size_t i = 0, l = txAntennas.size(); i < l; ++i)
m_clockSources << QString::fromStdString(clockSources[i]); m_txAntennas << QString::fromStdString(txAntennas[i]);
std::vector<std::string> rxAntennas = m_dev->get_rx_antennas();
m_rxAntennas.reserve(rxAntennas.size());
for(size_t i = 0, l = rxAntennas.size(); i < l; ++i)
m_rxAntennas << QString::fromStdString(rxAntennas[i]);
std::vector<std::string> rxGainNames = m_dev->get_rx_gain_names();
m_rxGainNames.reserve(rxGainNames.size());
for(size_t i = 0, l = rxGainNames.size(); i < l; ++i)
m_rxGainNames << QString::fromStdString(rxGainNames[i]);
std::vector<std::string> clockSources = m_dev->get_clock_sources(0);
m_clockSources.reserve(clockSources.size());
for(size_t i = 0, l = clockSources.size(); i < l; ++i)
m_clockSources << QString::fromStdString(clockSources[i]);
}
return true; return true;
} }

View File

@ -47,11 +47,6 @@ struct DEVICES_API DeviceUSRPParams
uhd::meta_range_t m_srRangeTx; //!< Sample rate range uhd::meta_range_t m_srRangeTx; //!< Sample rate range
uhd::gain_range_t m_gainRangeRx; //!< Gain range for Rx uhd::gain_range_t m_gainRangeRx; //!< Gain range for Rx
uhd::gain_range_t m_gainRangeTx; //!< Gain range for Tx uhd::gain_range_t m_gainRangeTx; //!< Gain range for Tx
float m_sampleRate; //!< Sample rate between host and device
int m_log2OvSRRx; //!< log2 of Rx oversampling (0..5)
int m_log2OvSRTx; //!< log2 of Tx oversampling (0..5)
float m_rxFrequency; //!< Rx frequency
float m_txFrequency; //!< Tx frequency
QStringList m_txAntennas; //!< List of Tx antenna names QStringList m_txAntennas; //!< List of Tx antenna names
QStringList m_rxAntennas; //!< List of Rx antenna names QStringList m_rxAntennas; //!< List of Rx antenna names
QStringList m_rxGainNames; //!< List of Rx gain stages - Currently this seems limited to "PGA" QStringList m_rxGainNames; //!< List of Rx gain stages - Currently this seems limited to "PGA"
@ -61,11 +56,6 @@ struct DEVICES_API DeviceUSRPParams
m_dev(), m_dev(),
m_nbRxChannels(0), m_nbRxChannels(0),
m_nbTxChannels(0), m_nbTxChannels(0),
m_sampleRate(1e6),
m_log2OvSRRx(0),
m_log2OvSRTx(0),
m_rxFrequency(1e6),
m_txFrequency(1e6),
m_lpfRangeRx(), m_lpfRangeRx(),
m_lpfRangeTx(), m_lpfRangeTx(),
m_loRangeRx(), m_loRangeRx(),
@ -84,7 +74,7 @@ struct DEVICES_API DeviceUSRPParams
/** /**
* Opens and initialize the device and obtain information (# channels, ranges, ...) * Opens and initialize the device and obtain information (# channels, ranges, ...)
*/ */
bool open(const char *deviceStr); bool open(const char *deviceStr, bool channelNumOnly);
void close(); void close();
uhd::usrp::multi_usrp::sptr getDevice() { return m_dev; } uhd::usrp::multi_usrp::sptr getDevice() { return m_dev; }

View File

@ -37,18 +37,21 @@ public:
int getDevSampleRate() const { return m_devSampleRate; } int getDevSampleRate() const { return m_devSampleRate; }
uint64_t getCenterFrequency() const { return m_centerFrequency; } uint64_t getCenterFrequency() const { return m_centerFrequency; }
int getLOOffset() const { return m_loOffset; } int getLOOffset() const { return m_loOffset; }
int getMasterClockRate() const { return m_masterClockRate; }
bool getRxElseTx() const { return m_rxElseTx; } bool getRxElseTx() const { return m_rxElseTx; }
static MsgReportBuddyChange* create( static MsgReportBuddyChange* create(
int devSampleRate, int devSampleRate,
uint64_t centerFrequency, uint64_t centerFrequency,
int loOffset, int loOffset,
int masterClockRate,
bool rxElseTx) bool rxElseTx)
{ {
return new MsgReportBuddyChange( return new MsgReportBuddyChange(
devSampleRate, devSampleRate,
centerFrequency, centerFrequency,
loOffset, loOffset,
masterClockRate,
rxElseTx); rxElseTx);
} }
@ -56,17 +59,20 @@ public:
int m_devSampleRate; //!< device/host sample rate int m_devSampleRate; //!< device/host sample rate
uint64_t m_centerFrequency; //!< Center frequency uint64_t m_centerFrequency; //!< Center frequency
int m_loOffset; //!< LO offset int m_loOffset; //!< LO offset
int m_masterClockRate; //!< FPGA/RFIC sample rate
bool m_rxElseTx; //!< tells which side initiated the message bool m_rxElseTx; //!< tells which side initiated the message
MsgReportBuddyChange( MsgReportBuddyChange(
int devSampleRate, int devSampleRate,
uint64_t centerFrequency, uint64_t centerFrequency,
int loOffset, int loOffset,
int masterClockRate,
bool rxElseTx) : bool rxElseTx) :
Message(), Message(),
m_devSampleRate(devSampleRate), m_devSampleRate(devSampleRate),
m_centerFrequency(centerFrequency), m_centerFrequency(centerFrequency),
m_loOffset(loOffset), m_loOffset(loOffset),
m_masterClockRate(masterClockRate),
m_rxElseTx(rxElseTx) m_rxElseTx(rxElseTx)
{ } { }
}; };

View File

@ -175,7 +175,7 @@ bool USRPOutput::openDevice()
m_deviceShared.m_deviceParams = new DeviceUSRPParams(); m_deviceShared.m_deviceParams = new DeviceUSRPParams();
char serial[256]; char serial[256];
strcpy(serial, qPrintable(m_deviceAPI->getSamplingDeviceSerial())); strcpy(serial, qPrintable(m_deviceAPI->getSamplingDeviceSerial()));
m_deviceShared.m_deviceParams->open(serial); m_deviceShared.m_deviceParams->open(serial, false);
m_deviceShared.m_channel = requestedChannel; // acknowledge the requested channel m_deviceShared.m_channel = requestedChannel; // acknowledge the requested channel
} }
@ -533,31 +533,31 @@ bool USRPOutput::handleMessage(const Message& message)
{ {
DeviceUSRPShared::MsgReportBuddyChange& report = (DeviceUSRPShared::MsgReportBuddyChange&) message; DeviceUSRPShared::MsgReportBuddyChange& report = (DeviceUSRPShared::MsgReportBuddyChange&) message;
if (report.getRxElseTx() && m_running) if (!report.getRxElseTx())
{
double host_Hz;
host_Hz = m_deviceShared.m_deviceParams->getDevice()->get_tx_rate(m_deviceShared.m_channel);
m_settings.m_devSampleRate = roundf(host_Hz);
qDebug() << "USRPOutput::handleMessage: MsgReportBuddyChange:"
<< " m_devSampleRate: " << m_settings.m_devSampleRate;
}
else
{ {
// Tx buddy changed settings, we need to copy
m_settings.m_devSampleRate = report.getDevSampleRate(); m_settings.m_devSampleRate = report.getDevSampleRate();
m_settings.m_centerFrequency = report.getCenterFrequency(); m_settings.m_centerFrequency = report.getCenterFrequency();
m_settings.m_loOffset = report.getLOOffset(); m_settings.m_loOffset = report.getLOOffset();
} }
// Master clock rate is common between all buddies
int masterClockRate = report.getMasterClockRate();
if (masterClockRate > 0)
m_settings.m_masterClockRate = masterClockRate;
qDebug() << "USRPOutput::handleMessage MsgReportBuddyChange";
qDebug() << "m_masterClockRate " << m_settings.m_masterClockRate;
DSPSignalNotification *notif = new DSPSignalNotification( DSPSignalNotification *notif = new DSPSignalNotification(
m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftInterp), m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftInterp),
m_settings.m_centerFrequency); m_settings.m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
DeviceUSRPShared::MsgReportBuddyChange *reportToGUI = DeviceUSRPShared::MsgReportBuddyChange::create( if (getMessageQueueToGUI())
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, false); {
getMessageQueueToGUI()->push(reportToGUI); DeviceUSRPShared::MsgReportBuddyChange *reportToGUI = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, false);
getMessageQueueToGUI()->push(reportToGUI);
}
return true; return true;
} }
@ -617,6 +617,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool preGetSt
bool forwardChangeAllDSP = false; bool forwardChangeAllDSP = false;
bool forwardClockSource = false; bool forwardClockSource = false;
bool ownThreadWasRunning = false; bool ownThreadWasRunning = false;
bool checkRates = false;
QList<QString> reverseAPIKeys; QList<QString> reverseAPIKeys;
try try
@ -665,10 +666,8 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool preGetSt
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream)) if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
{ {
m_deviceShared.m_deviceParams->getDevice()->set_tx_rate(settings.m_devSampleRate, m_deviceShared.m_channel); m_deviceShared.m_deviceParams->getDevice()->set_tx_rate(settings.m_devSampleRate, m_deviceShared.m_channel);
double actualSampleRate = m_deviceShared.m_deviceParams->getDevice()->get_tx_rate(m_deviceShared.m_channel); qDebug("USRPOutput::applySettings: set sample rate set to %d", settings.m_devSampleRate);
qDebug("USRPOutput::applySettings: set sample rate set to %d - actual rate %f", settings.m_devSampleRate, checkRates = true;
actualSampleRate);
m_deviceShared.m_deviceParams->m_sampleRate = m_settings.m_devSampleRate;
} }
} }
@ -776,6 +775,17 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool preGetSt
m_settings = settings; m_settings = settings;
if (checkRates)
{
// Check if requested rate could actually be met and what master clock rate we ended up with
double actualSampleRate = m_deviceShared.m_deviceParams->getDevice()->get_tx_rate(m_deviceShared.m_channel);
qDebug("USRPOutput::applySettings: actual sample rate %f", actualSampleRate);
double masterClockRate = m_deviceShared.m_deviceParams->getDevice()->get_master_clock_rate();
qDebug("USRPOutput::applySettings: master_clock_rate %f", masterClockRate);
m_settings.m_devSampleRate = actualSampleRate;
m_settings.m_masterClockRate = masterClockRate;
}
// forward changes to buddies or oneself // forward changes to buddies or oneself
if (forwardChangeAllDSP) if (forwardChangeAllDSP)
@ -795,7 +805,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool preGetSt
for (; itSink != sinkBuddies.end(); ++itSink) for (; itSink != sinkBuddies.end(); ++itSink)
{ {
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create( DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, false); m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, false);
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report); (*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
} }
@ -806,9 +816,17 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool preGetSt
for (; itSource != sourceBuddies.end(); ++itSource) for (; itSource != sourceBuddies.end(); ++itSource)
{ {
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create( DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, false); m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, false);
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report); (*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
} }
// send to GUI so it can see master clock rate and if actual rate differs
if (m_deviceAPI->getSamplingDeviceGUIMessageQueue())
{
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, false);
m_deviceAPI->getSamplingDeviceGUIMessageQueue()->push(report);
}
} }
else if (forwardChangeTxDSP) else if (forwardChangeTxDSP)
{ {
@ -827,7 +845,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool preGetSt
for (; itSink != sinkBuddies.end(); ++itSink) for (; itSink != sinkBuddies.end(); ++itSink)
{ {
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create( DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, false); m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, false);
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report); (*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
} }
} }
@ -856,6 +874,14 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool preGetSt
} }
} }
// send to GUI in case requested clock isn't detected
if (m_deviceAPI->getSamplingDeviceGUIMessageQueue())
{
DeviceUSRPShared::MsgReportClockSourceChange *report = DeviceUSRPShared::MsgReportClockSourceChange::create(
m_settings.m_clockSource);
m_deviceAPI->getSamplingDeviceGUIMessageQueue()->push(report);
}
// send to source buddies // send to source buddies
const std::vector<DeviceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies(); const std::vector<DeviceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
std::vector<DeviceAPI*>::const_iterator itSource = sourceBuddies.begin(); std::vector<DeviceAPI*>::const_iterator itSource = sourceBuddies.begin();

View File

@ -180,9 +180,10 @@ bool USRPOutputGUI::handleMessage(const Message& message)
else if (DeviceUSRPShared::MsgReportBuddyChange::match(message)) else if (DeviceUSRPShared::MsgReportBuddyChange::match(message))
{ {
DeviceUSRPShared::MsgReportBuddyChange& report = (DeviceUSRPShared::MsgReportBuddyChange&) message; DeviceUSRPShared::MsgReportBuddyChange& report = (DeviceUSRPShared::MsgReportBuddyChange&) message;
m_settings.m_devSampleRate = report.getDevSampleRate(); m_settings.m_masterClockRate = report.getMasterClockRate();
if (!report.getRxElseTx()) { if (!report.getRxElseTx()) {
m_settings.m_devSampleRate = report.getDevSampleRate();
m_settings.m_centerFrequency = report.getCenterFrequency(); m_settings.m_centerFrequency = report.getCenterFrequency();
m_settings.m_loOffset = report.getLOOffset(); m_settings.m_loOffset = report.getLOOffset();
} }
@ -291,12 +292,20 @@ void USRPOutputGUI::updateSampleRateAndFrequency()
void USRPOutputGUI::updateSampleRate() void USRPOutputGUI::updateSampleRate()
{ {
uint32_t sr = m_settings.m_devSampleRate; uint32_t sr = m_settings.m_devSampleRate;
int cr = m_settings.m_masterClockRate;
if (sr < 100000000) { if (sr < 100000000) {
ui->sampleRateLabel->setText(tr("%1k").arg(QString::number(sr / 1000.0f, 'g', 5))); ui->sampleRateLabel->setText(tr("%1k").arg(QString::number(sr / 1000.0f, 'g', 5)));
} else { } else {
ui->sampleRateLabel->setText(tr("%1M").arg(QString::number(sr / 1000000.0f, 'g', 5))); ui->sampleRateLabel->setText(tr("%1M").arg(QString::number(sr / 1000000.0f, 'g', 5)));
} }
if (cr < 0) {
ui->masterClockRateLabel->setText("-");
} else if (cr < 100000000) {
ui->masterClockRateLabel->setText(tr("%1k").arg(QString::number(cr / 1000.0f, 'g', 5)));
} else {
ui->masterClockRateLabel->setText(tr("%1M").arg(QString::number(cr / 1000000.0f, 'g', 5)));
}
// LO offset shouldn't be greater than half the sample rate // 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); ui->loOffset->setValueRange(false, 5, -(int32_t)sr/2/1000, (int32_t)sr/2/1000);
} }

View File

@ -75,6 +75,16 @@
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="freqLeftBotLayout"> <layout class="QHBoxLayout" name="freqLeftBotLayout">
<item>
<widget class="QLabel" name="masterClockRateLabel">
<property name="toolTip">
<string>Master clock rate (sample rate between FPGA and RFIC) (k or MS/s)</string>
</property>
<property name="text">
<string>00000k</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QLabel" name="sampleRateLabel"> <widget class="QLabel" name="sampleRateLabel">
<property name="minimumSize"> <property name="minimumSize">

View File

@ -27,6 +27,7 @@ USRPOutputSettings::USRPOutputSettings()
void USRPOutputSettings::resetToDefaults() void USRPOutputSettings::resetToDefaults()
{ {
m_masterClockRate = -1; // Calculated by UHD
m_centerFrequency = 435000*1000; m_centerFrequency = 435000*1000;
m_devSampleRate = 3000000; m_devSampleRate = 3000000;
m_loOffset = 0; m_loOffset = 0;

View File

@ -30,6 +30,7 @@
*/ */
struct USRPOutputSettings struct USRPOutputSettings
{ {
int m_masterClockRate;
// global settings to be saved // global settings to be saved
uint64_t m_centerFrequency; uint64_t m_centerFrequency;
int m_devSampleRate; int m_devSampleRate;

View File

@ -202,7 +202,7 @@ bool USRPInput::openDevice()
m_deviceShared.m_deviceParams = new DeviceUSRPParams(); m_deviceShared.m_deviceParams = new DeviceUSRPParams();
char serial[256]; char serial[256];
strcpy(serial, qPrintable(m_deviceAPI->getSamplingDeviceSerial())); strcpy(serial, qPrintable(m_deviceAPI->getSamplingDeviceSerial()));
m_deviceShared.m_deviceParams->open(serial); m_deviceShared.m_deviceParams->open(serial, false);
m_deviceShared.m_channel = requestedChannel; // acknowledge the requested channel m_deviceShared.m_channel = requestedChannel; // acknowledge the requested channel
} }
@ -548,20 +548,17 @@ bool USRPInput::handleMessage(const Message& message)
if (report.getRxElseTx()) if (report.getRxElseTx())
{ {
// Rx buddy changed settings, we need to copy
m_settings.m_devSampleRate = report.getDevSampleRate(); m_settings.m_devSampleRate = report.getDevSampleRate();
m_settings.m_centerFrequency = report.getCenterFrequency(); m_settings.m_centerFrequency = report.getCenterFrequency();
m_settings.m_loOffset = report.getLOOffset(); m_settings.m_loOffset = report.getLOOffset();
} }
else if (m_running) // Master clock rate is common between all buddies
{ int masterClockRate = report.getMasterClockRate();
double host_Hz; if (masterClockRate > 0)
m_settings.m_masterClockRate = masterClockRate;
host_Hz = m_deviceShared.m_deviceParams->getDevice()->get_rx_rate(m_deviceShared.m_channel); qDebug() << "USRPInput::handleMessage MsgReportBuddyChange";
m_settings.m_devSampleRate = roundf(host_Hz); qDebug() << "m_masterClockRate " << m_settings.m_masterClockRate;
qDebug() << "USRPInput::handleMessage: MsgReportBuddyChange:"
<< " m_devSampleRate: " << m_settings.m_devSampleRate;
}
DSPSignalNotification *notif = new DSPSignalNotification( DSPSignalNotification *notif = new DSPSignalNotification(
m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftDecim), m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftDecim),
@ -571,7 +568,7 @@ bool USRPInput::handleMessage(const Message& message)
if (getMessageQueueToGUI()) if (getMessageQueueToGUI())
{ {
DeviceUSRPShared::MsgReportBuddyChange *reportToGUI = DeviceUSRPShared::MsgReportBuddyChange::create( DeviceUSRPShared::MsgReportBuddyChange *reportToGUI = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true); m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, true);
getMessageQueueToGUI()->push(reportToGUI); getMessageQueueToGUI()->push(reportToGUI);
} }
@ -656,6 +653,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool preGetStre
bool forwardClockSource = false; bool forwardClockSource = false;
bool ownThreadWasRunning = false; bool ownThreadWasRunning = false;
bool reapplySomeSettings = false; bool reapplySomeSettings = false;
bool checkRates = false;
QList<QString> reverseAPIKeys; QList<QString> reverseAPIKeys;
try try
@ -704,10 +702,8 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool preGetStre
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream)) if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
{ {
m_deviceShared.m_deviceParams->getDevice()->set_rx_rate(settings.m_devSampleRate, m_deviceShared.m_channel); 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); qDebug("USRPInput::applySettings: set sample rate set to %d", settings.m_devSampleRate);
qDebug("USRPInput::applySettings: set sample rate set to %d - actual rate %f", settings.m_devSampleRate, checkRates = true;
actualSampleRate);
m_deviceShared.m_deviceParams->m_sampleRate = m_settings.m_devSampleRate;
reapplySomeSettings = true; reapplySomeSettings = true;
} }
} }
@ -845,6 +841,17 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool preGetStre
m_settings = settings; m_settings = settings;
if (checkRates)
{
// Check if requested rate could actually be met and what master clock rate we ended up with
double actualSampleRate = m_deviceShared.m_deviceParams->getDevice()->get_rx_rate(m_deviceShared.m_channel);
qDebug("USRPInput::applySettings: actual sample rate %f", actualSampleRate);
double masterClockRate = m_deviceShared.m_deviceParams->getDevice()->get_master_clock_rate();
qDebug("USRPInput::applySettings: master_clock_rate %f", masterClockRate);
m_settings.m_devSampleRate = actualSampleRate;
m_settings.m_masterClockRate = masterClockRate;
}
// forward changes to buddies or oneself // forward changes to buddies or oneself
if (forwardChangeAllDSP) if (forwardChangeAllDSP)
@ -864,7 +871,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool preGetStre
for (; itSource != sourceBuddies.end(); ++itSource) for (; itSource != sourceBuddies.end(); ++itSource)
{ {
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create( DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true); m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, true);
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report); (*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
} }
@ -875,9 +882,17 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool preGetStre
for (; itSink != sinkBuddies.end(); ++itSink) for (; itSink != sinkBuddies.end(); ++itSink)
{ {
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create( DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true); m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, true);
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report); (*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
} }
// send to GUI so it can see master clock rate and if actual rate differs
if (m_deviceAPI->getSamplingDeviceGUIMessageQueue())
{
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, true);
m_deviceAPI->getSamplingDeviceGUIMessageQueue()->push(report);
}
} }
else if (forwardChangeRxDSP) else if (forwardChangeRxDSP)
{ {
@ -896,7 +911,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool preGetStre
for (; itSource != sourceBuddies.end(); ++itSource) for (; itSource != sourceBuddies.end(); ++itSource)
{ {
DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create( DeviceUSRPShared::MsgReportBuddyChange *report = DeviceUSRPShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true); m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, m_settings.m_masterClockRate, true);
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report); (*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
} }
} }

View File

@ -163,9 +163,10 @@ bool USRPInputGUI::handleMessage(const Message& message)
else if (DeviceUSRPShared::MsgReportBuddyChange::match(message)) else if (DeviceUSRPShared::MsgReportBuddyChange::match(message))
{ {
DeviceUSRPShared::MsgReportBuddyChange& report = (DeviceUSRPShared::MsgReportBuddyChange&) message; DeviceUSRPShared::MsgReportBuddyChange& report = (DeviceUSRPShared::MsgReportBuddyChange&) message;
m_settings.m_devSampleRate = report.getDevSampleRate(); m_settings.m_masterClockRate = report.getMasterClockRate();
if (report.getRxElseTx()) { if (report.getRxElseTx()) {
m_settings.m_devSampleRate = report.getDevSampleRate();
m_settings.m_centerFrequency = report.getCenterFrequency(); m_settings.m_centerFrequency = report.getCenterFrequency();
m_settings.m_loOffset = report.getLOOffset(); m_settings.m_loOffset = report.getLOOffset();
} }
@ -287,12 +288,20 @@ void USRPInputGUI::handleInputMessages()
void USRPInputGUI::updateSampleRate() void USRPInputGUI::updateSampleRate()
{ {
uint32_t sr = m_settings.m_devSampleRate; uint32_t sr = m_settings.m_devSampleRate;
int cr = m_settings.m_masterClockRate;
if (sr < 100000000) { if (sr < 100000000) {
ui->sampleRateLabel->setText(tr("%1k").arg(QString::number(sr / 1000.0f, 'g', 5))); ui->sampleRateLabel->setText(tr("%1k").arg(QString::number(sr / 1000.0f, 'g', 5)));
} else { } else {
ui->sampleRateLabel->setText(tr("%1M").arg(QString::number(sr / 1000000.0f, 'g', 5))); ui->sampleRateLabel->setText(tr("%1M").arg(QString::number(sr / 1000000.0f, 'g', 5)));
} }
if (cr < 0) {
ui->masterClockRateLabel->setText("-");
} else if (cr < 100000000) {
ui->masterClockRateLabel->setText(tr("%1k").arg(QString::number(cr / 1000.0f, 'g', 5)));
} else {
ui->masterClockRateLabel->setText(tr("%1M").arg(QString::number(cr / 1000000.0f, 'g', 5)));
}
// LO offset shouldn't be greater than half the sample rate // 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); ui->loOffset->setValueRange(false, 5, -(int32_t)sr/2/1000, (int32_t)sr/2/1000);
} }

View File

@ -75,6 +75,16 @@
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="freqLeftBotLayout"> <layout class="QHBoxLayout" name="freqLeftBotLayout">
<item>
<widget class="QLabel" name="masterClockRateLabel">
<property name="toolTip">
<string>Master clock rate (sample rate between FPGA and RFIC) (k or MS/s)</string>
</property>
<property name="text">
<string>00000k</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QLabel" name="sampleRateLabel"> <widget class="QLabel" name="sampleRateLabel">
<property name="minimumSize"> <property name="minimumSize">
@ -799,17 +809,17 @@
<header>gui/valuedial.h</header> <header>gui/valuedial.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>TransverterButton</class>
<extends>QPushButton</extends>
<header>gui/transverterbutton.h</header>
</customwidget>
<customwidget> <customwidget>
<class>ValueDialZ</class> <class>ValueDialZ</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>gui/valuedialz.h</header> <header>gui/valuedialz.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>TransverterButton</class>
<extends>QPushButton</extends>
<header>gui/transverterbutton.h</header>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../../../sdrgui/resources/res.qrc"/> <include location="../../../sdrgui/resources/res.qrc"/>

View File

@ -26,6 +26,7 @@ USRPInputSettings::USRPInputSettings()
void USRPInputSettings::resetToDefaults() void USRPInputSettings::resetToDefaults()
{ {
m_masterClockRate = -1; // Calculated by UHD
m_centerFrequency = 435000*1000; m_centerFrequency = 435000*1000;
m_devSampleRate = 3000000; m_devSampleRate = 3000000;
m_loOffset = 0; m_loOffset = 0;

View File

@ -34,6 +34,7 @@ struct USRPInputSettings
GAIN_MANUAL GAIN_MANUAL
} GainMode; } GainMode;
int m_masterClockRate;
// global settings to be saved // global settings to be saved
uint64_t m_centerFrequency; uint64_t m_centerFrequency;
int m_devSampleRate; int m_devSampleRate;