mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 17:28:50 -05: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:
parent
209be94947
commit
d8ae6fc765
@ -69,3 +69,31 @@ void DeviceUSRP::enumOriginDevices(const QString& hardwareId, PluginInterface::O
|
|||||||
qDebug() << "DeviceUSRP::enumOriginDevices: exception: " << e.what();
|
qDebug() << "DeviceUSRP::enumOriginDevices: exception: " << e.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceUSRP::waitForLock(uhd::usrp::multi_usrp::sptr usrp, const QString& clockSource, int channel)
|
||||||
|
{
|
||||||
|
int tries;
|
||||||
|
const int maxTries = 100;
|
||||||
|
|
||||||
|
// Wait for Ref lock
|
||||||
|
std::vector<std::string> sensor_names;
|
||||||
|
sensor_names = usrp->get_tx_sensor_names(channel);
|
||||||
|
if (clockSource == "external")
|
||||||
|
{
|
||||||
|
if (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())
|
||||||
|
{
|
||||||
|
for (tries = 0; !usrp->get_mboard_sensor("ref_locked", 0).to_bool() && (tries < maxTries); tries++)
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
if (tries == maxTries)
|
||||||
|
qCritical("USRPInput::acquireChannel: Failed to lock ref");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Wait for LO lock
|
||||||
|
if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end())
|
||||||
|
{
|
||||||
|
for (tries = 0; !usrp->get_tx_sensor("lo_locked", channel).to_bool() && (tries < maxTries); tries++)
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
if (tries == maxTries)
|
||||||
|
qCritical("USRPInput::acquireChannel: Failed to lock LO");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -33,6 +33,8 @@ public:
|
|||||||
/** Enumeration of USRP hardware devices */
|
/** Enumeration of USRP hardware devices */
|
||||||
static void enumOriginDevices(const QString& hardwareId, PluginInterface::OriginDevices& originDevices);
|
static void enumOriginDevices(const QString& hardwareId, PluginInterface::OriginDevices& originDevices);
|
||||||
|
|
||||||
|
/** Wait for ref clock and LO to lock */
|
||||||
|
static void waitForLock(uhd::usrp::multi_usrp::sptr usrp, const QString& clockSource, int channel);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DEVICES_USRP_DEVICEUSRP_H_ */
|
#endif /* DEVICES_USRP_DEVICEUSRP_H_ */
|
||||||
|
@ -36,31 +36,37 @@ public:
|
|||||||
public:
|
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; }
|
||||||
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,
|
||||||
bool rxElseTx)
|
bool rxElseTx)
|
||||||
{
|
{
|
||||||
return new MsgReportBuddyChange(
|
return new MsgReportBuddyChange(
|
||||||
devSampleRate,
|
devSampleRate,
|
||||||
centerFrequency,
|
centerFrequency,
|
||||||
|
loOffset,
|
||||||
rxElseTx);
|
rxElseTx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
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
|
||||||
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,
|
||||||
bool rxElseTx) :
|
bool rxElseTx) :
|
||||||
Message(),
|
Message(),
|
||||||
m_devSampleRate(devSampleRate),
|
m_devSampleRate(devSampleRate),
|
||||||
m_centerFrequency(centerFrequency),
|
m_centerFrequency(centerFrequency),
|
||||||
|
m_loOffset(loOffset),
|
||||||
m_rxElseTx(rxElseTx)
|
m_rxElseTx(rxElseTx)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
@ -293,6 +293,13 @@ bool USRPOutput::acquireChannel()
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
uhd::usrp::multi_usrp::sptr usrp = m_deviceShared.m_deviceParams->getDevice();
|
||||||
|
|
||||||
|
// 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_tx_bandwidth(56000000, m_deviceShared.m_channel);
|
||||||
|
|
||||||
// set up the stream
|
// set up the stream
|
||||||
std::string cpu_format("sc16");
|
std::string cpu_format("sc16");
|
||||||
std::string wire_format("sc16");
|
std::string wire_format("sc16");
|
||||||
@ -302,10 +309,16 @@ bool USRPOutput::acquireChannel()
|
|||||||
uhd::stream_args_t stream_args(cpu_format, wire_format);
|
uhd::stream_args_t stream_args(cpu_format, wire_format);
|
||||||
stream_args.channels = channel_nums;
|
stream_args.channels = channel_nums;
|
||||||
|
|
||||||
m_streamId = m_deviceShared.m_deviceParams->getDevice()->get_tx_stream(stream_args);
|
m_streamId = usrp->get_tx_stream(stream_args);
|
||||||
|
|
||||||
// Match our transmit buffer size to what UHD uses
|
// Match our transmit buffer size to what UHD uses
|
||||||
m_bufSamples = m_streamId->get_max_num_samps();
|
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_tx_bandwidth(m_settings.m_lpfBW, m_deviceShared.m_channel);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
@ -326,14 +339,8 @@ void USRPOutput::releaseChannel()
|
|||||||
suspendRxBuddies();
|
suspendRxBuddies();
|
||||||
suspendTxBuddies();
|
suspendTxBuddies();
|
||||||
|
|
||||||
// FIXME: Currently we do not try to destroy the stream, as there seems to be
|
// destroy the stream
|
||||||
// an issue when we re-acquire the stream, the output spectrum will not be correct
|
m_streamId = nullptr;
|
||||||
// The transmitter output will be disabled when we stop sending data to it anyway
|
|
||||||
if (false)
|
|
||||||
{
|
|
||||||
// destroy the stream
|
|
||||||
m_streamId = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
resumeTxBuddies();
|
resumeTxBuddies();
|
||||||
resumeRxBuddies();
|
resumeRxBuddies();
|
||||||
@ -343,7 +350,7 @@ void USRPOutput::releaseChannel()
|
|||||||
|
|
||||||
void USRPOutput::init()
|
void USRPOutput::init()
|
||||||
{
|
{
|
||||||
applySettings(m_settings, true);
|
applySettings(m_settings, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USRPOutput::start()
|
bool USRPOutput::start()
|
||||||
@ -362,8 +369,6 @@ bool USRPOutput::start()
|
|||||||
m_usrpOutputThread = new USRPOutputThread(m_streamId, m_bufSamples, &m_sampleSourceFifo);
|
m_usrpOutputThread = new USRPOutputThread(m_streamId, m_bufSamples, &m_sampleSourceFifo);
|
||||||
qDebug("USRPOutput::start: thread created");
|
qDebug("USRPOutput::start: thread created");
|
||||||
|
|
||||||
applySettings(m_settings, true);
|
|
||||||
|
|
||||||
m_usrpOutputThread->setLog2Interpolation(m_settings.m_log2SoftInterp);
|
m_usrpOutputThread->setLog2Interpolation(m_settings.m_log2SoftInterp);
|
||||||
m_usrpOutputThread->startWork();
|
m_usrpOutputThread->startWork();
|
||||||
|
|
||||||
@ -494,7 +499,7 @@ bool USRPOutput::handleMessage(const Message& message)
|
|||||||
MsgConfigureUSRP& conf = (MsgConfigureUSRP&) message;
|
MsgConfigureUSRP& conf = (MsgConfigureUSRP&) message;
|
||||||
qDebug() << "USRPOutput::handleMessage: MsgConfigureUSRP";
|
qDebug() << "USRPOutput::handleMessage: MsgConfigureUSRP";
|
||||||
|
|
||||||
if (!applySettings(conf.getSettings(), conf.getForce()))
|
if (!applySettings(conf.getSettings(), false, conf.getForce()))
|
||||||
{
|
{
|
||||||
qDebug("USRPOutput::handleMessage config error");
|
qDebug("USRPOutput::handleMessage config error");
|
||||||
}
|
}
|
||||||
@ -542,6 +547,7 @@ bool USRPOutput::handleMessage(const Message& message)
|
|||||||
{
|
{
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
DSPSignalNotification *notif = new DSPSignalNotification(
|
DSPSignalNotification *notif = new DSPSignalNotification(
|
||||||
@ -550,7 +556,7 @@ bool USRPOutput::handleMessage(const Message& message)
|
|||||||
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
|
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
|
||||||
|
|
||||||
DeviceUSRPShared::MsgReportBuddyChange *reportToGUI = DeviceUSRPShared::MsgReportBuddyChange::create(
|
DeviceUSRPShared::MsgReportBuddyChange *reportToGUI = DeviceUSRPShared::MsgReportBuddyChange::create(
|
||||||
m_settings.m_devSampleRate, m_settings.m_centerFrequency, false);
|
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, false);
|
||||||
getMessageQueueToGUI()->push(reportToGUI);
|
getMessageQueueToGUI()->push(reportToGUI);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -604,7 +610,7 @@ bool USRPOutput::handleMessage(const Message& message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool preGetStream, bool force)
|
||||||
{
|
{
|
||||||
bool forwardChangeOwnDSP = false;
|
bool forwardChangeOwnDSP = false;
|
||||||
bool forwardChangeTxDSP = false;
|
bool forwardChangeTxDSP = false;
|
||||||
@ -626,7 +632,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
reverseAPIKeys.append("clockSource");
|
reverseAPIKeys.append("clockSource");
|
||||||
|
|
||||||
if (m_deviceShared.m_deviceParams->getDevice())
|
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -656,7 +662,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
reverseAPIKeys.append("devSampleRate");
|
reverseAPIKeys.append("devSampleRate");
|
||||||
forwardChangeAllDSP = true;
|
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_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);
|
double actualSampleRate = m_deviceShared.m_deviceParams->getDevice()->get_tx_rate(m_deviceShared.m_channel);
|
||||||
@ -667,6 +673,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((m_settings.m_centerFrequency != settings.m_centerFrequency)
|
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_transverterMode != settings.m_transverterMode)
|
||||||
|| (m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency)
|
|| (m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency)
|
||||||
|| force)
|
|| force)
|
||||||
@ -676,12 +683,20 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
reverseAPIKeys.append("transverterDeltaFrequency");
|
reverseAPIKeys.append("transverterDeltaFrequency");
|
||||||
forwardChangeTxDSP = true;
|
forwardChangeTxDSP = 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);
|
if (settings.m_loOffset != 0)
|
||||||
m_deviceShared.m_deviceParams->getDevice()->set_tx_freq(tune_request, m_deviceShared.m_channel);
|
{
|
||||||
|
uhd::tune_request_t tune_request(deviceCenterFrequency, settings.m_loOffset);
|
||||||
|
m_deviceShared.m_deviceParams->getDevice()->set_tx_freq(tune_request, m_deviceShared.m_channel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uhd::tune_request_t tune_request(deviceCenterFrequency);
|
||||||
|
m_deviceShared.m_deviceParams->getDevice()->set_tx_freq(tune_request, m_deviceShared.m_channel);
|
||||||
|
}
|
||||||
m_deviceShared.m_centerFrequency = deviceCenterFrequency; // for buddies
|
m_deviceShared.m_centerFrequency = deviceCenterFrequency; // for buddies
|
||||||
qDebug("USRPOutput::applySettings: frequency set to %lld", deviceCenterFrequency);
|
qDebug("USRPOutput::applySettings: frequency set to %lld with LO offset %d", deviceCenterFrequency, settings.m_loOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,7 +722,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
reverseAPIKeys.append("gain");
|
reverseAPIKeys.append("gain");
|
||||||
|
|
||||||
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
|
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
|
||||||
{
|
{
|
||||||
m_deviceShared.m_deviceParams->getDevice()->set_tx_gain(settings.m_gain, m_deviceShared.m_channel);
|
m_deviceShared.m_deviceParams->getDevice()->set_tx_gain(settings.m_gain, m_deviceShared.m_channel);
|
||||||
qDebug() << "USRPOutput::applySettings: Gain set to " << settings.m_gain;
|
qDebug() << "USRPOutput::applySettings: Gain set to " << settings.m_gain;
|
||||||
@ -718,6 +733,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
reverseAPIKeys.append("lpfBW");
|
reverseAPIKeys.append("lpfBW");
|
||||||
|
|
||||||
|
// Don't set bandwidth before get_tx_stream (See above)
|
||||||
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
|
if (m_deviceShared.m_deviceParams->getDevice() && m_channelAcquired)
|
||||||
{
|
{
|
||||||
m_deviceShared.m_deviceParams->getDevice()->set_tx_bandwidth(settings.m_lpfBW, m_deviceShared.m_channel);
|
m_deviceShared.m_deviceParams->getDevice()->set_tx_bandwidth(settings.m_lpfBW, m_deviceShared.m_channel);
|
||||||
@ -742,7 +758,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
reverseAPIKeys.append("antennaPath");
|
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_tx_antenna(settings.m_antennaPath.toStdString(), m_deviceShared.m_channel);
|
m_deviceShared.m_deviceParams->getDevice()->set_tx_antenna(settings.m_antennaPath.toStdString(), m_deviceShared.m_channel);
|
||||||
qDebug("USRPOutput::applySettings: set antenna path to %s on channel %d", qPrintable(settings.m_antennaPath), m_deviceShared.m_channel);
|
qDebug("USRPOutput::applySettings: set antenna path to %s on channel %d", qPrintable(settings.m_antennaPath), m_deviceShared.m_channel);
|
||||||
@ -779,7 +795,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
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, false);
|
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, false);
|
||||||
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
|
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,7 +806,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
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, false);
|
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, false);
|
||||||
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
|
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -811,7 +827,7 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, bool force)
|
|||||||
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, false);
|
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, false);
|
||||||
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
|
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1035,7 +1051,7 @@ void USRPOutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response
|
|||||||
quint32 underflows = 0;
|
quint32 underflows = 0;
|
||||||
quint32 droppedPackets = 0;
|
quint32 droppedPackets = 0;
|
||||||
|
|
||||||
if ((m_streamId != nullptr) && m_channelAcquired)
|
if ((m_streamId != nullptr) && (m_usrpOutputThread != nullptr) && m_channelAcquired)
|
||||||
{
|
{
|
||||||
m_usrpOutputThread->getStreamStatus(active, underflows, droppedPackets);
|
m_usrpOutputThread->getStreamStatus(active, underflows, droppedPackets);
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -238,7 +238,7 @@ private:
|
|||||||
void resumeRxBuddies();
|
void resumeRxBuddies();
|
||||||
void suspendTxBuddies();
|
void suspendTxBuddies();
|
||||||
void resumeTxBuddies();
|
void resumeTxBuddies();
|
||||||
bool applySettings(const USRPOutputSettings& settings, bool force = false);
|
bool applySettings(const USRPOutputSettings& settings, bool preGetStream, bool force = false);
|
||||||
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
|
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
|
||||||
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const USRPOutputSettings& settings, bool force);
|
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const USRPOutputSettings& settings, bool force);
|
||||||
void webapiReverseSendStartStop(bool start);
|
void webapiReverseSendStartStop(bool start);
|
||||||
|
@ -57,6 +57,9 @@ USRPOutputGUI::USRPOutputGUI(DeviceUISet *deviceUISet, QWidget* parent) :
|
|||||||
ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
|
ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
|
||||||
ui->sampleRate->setValueRange(8, (uint32_t) minF, (uint32_t) maxF);
|
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_usrpOutput->getLPRange(minF, maxF);
|
m_usrpOutput->getLPRange(minF, maxF);
|
||||||
ui->lpf->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
ui->lpf->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
||||||
ui->lpf->setValueRange(5, (minF/1000)+1, maxF/1000);
|
ui->lpf->setValueRange(5, (minF/1000)+1, maxF/1000);
|
||||||
@ -181,6 +184,7 @@ bool USRPOutputGUI::handleMessage(const Message& message)
|
|||||||
|
|
||||||
if (!report.getRxElseTx()) {
|
if (!report.getRxElseTx()) {
|
||||||
m_settings.m_centerFrequency = report.getCenterFrequency();
|
m_settings.m_centerFrequency = report.getCenterFrequency();
|
||||||
|
m_settings.m_loOffset = report.getLOOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
blockApplySettings(true);
|
blockApplySettings(true);
|
||||||
@ -293,6 +297,8 @@ void USRPOutputGUI::updateSampleRate()
|
|||||||
} 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)));
|
||||||
}
|
}
|
||||||
|
// 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 USRPOutputGUI::displaySampleRate()
|
void USRPOutputGUI::displaySampleRate()
|
||||||
@ -343,6 +349,7 @@ void USRPOutputGUI::displaySettings()
|
|||||||
updateSampleRate();
|
updateSampleRate();
|
||||||
|
|
||||||
ui->lpf->setValue(m_settings.m_lpfBW / 1000);
|
ui->lpf->setValue(m_settings.m_lpfBW / 1000);
|
||||||
|
ui->loOffset->setValue(m_settings.m_loOffset / 1000);
|
||||||
|
|
||||||
ui->gain->setValue(m_settings.m_gain);
|
ui->gain->setValue(m_settings.m_gain);
|
||||||
ui->gainText->setText(tr("%1dB").arg(m_settings.m_gain));
|
ui->gainText->setText(tr("%1dB").arg(m_settings.m_gain));
|
||||||
@ -497,6 +504,12 @@ void USRPOutputGUI::on_lpf_changed(quint64 value)
|
|||||||
sendSettings();
|
sendSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USRPOutputGUI::on_loOffset_changed(qint64 value)
|
||||||
|
{
|
||||||
|
m_settings.m_loOffset = value * 1000;
|
||||||
|
sendSettings();
|
||||||
|
}
|
||||||
|
|
||||||
void USRPOutputGUI::on_gain_valueChanged(int value)
|
void USRPOutputGUI::on_gain_valueChanged(int value)
|
||||||
{
|
{
|
||||||
m_settings.m_gain = value;
|
m_settings.m_gain = value;
|
||||||
|
@ -88,6 +88,7 @@ private slots:
|
|||||||
void on_sampleRate_changed(quint64 value);
|
void on_sampleRate_changed(quint64 value);
|
||||||
void on_swInterp_currentIndexChanged(int index);
|
void on_swInterp_currentIndexChanged(int index);
|
||||||
void on_lpf_changed(quint64 value);
|
void on_lpf_changed(quint64 value);
|
||||||
|
void on_loOffset_changed(qint64 value);
|
||||||
void on_gain_valueChanged(int value);
|
void on_gain_valueChanged(int value);
|
||||||
void on_antenna_currentIndexChanged(int index);
|
void on_antenna_currentIndexChanged(int index);
|
||||||
void on_clockSource_currentIndexChanged(int index);
|
void on_clockSource_currentIndexChanged(int index);
|
||||||
|
@ -562,6 +562,55 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line_3">
|
||||||
|
<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>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>LO frequency offset. This should not be greater than half the sample rate.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="loOffsetUnits">
|
||||||
|
<property name="text">
|
||||||
|
<string>kHz</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -684,6 +733,12 @@
|
|||||||
<header>gui/valuedial.h</header>
|
<header>gui/valuedial.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>ValueDialZ</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>gui/valuedialz.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>TransverterButton</class>
|
<class>TransverterButton</class>
|
||||||
<extends>QPushButton</extends>
|
<extends>QPushButton</extends>
|
||||||
|
@ -29,8 +29,9 @@ void USRPOutputSettings::resetToDefaults()
|
|||||||
{
|
{
|
||||||
m_centerFrequency = 435000*1000;
|
m_centerFrequency = 435000*1000;
|
||||||
m_devSampleRate = 3000000;
|
m_devSampleRate = 3000000;
|
||||||
|
m_loOffset = 0;
|
||||||
m_log2SoftInterp = 0;
|
m_log2SoftInterp = 0;
|
||||||
m_lpfBW = 5.5e6f;
|
m_lpfBW = 10e6f;
|
||||||
m_gain = 50;
|
m_gain = 50;
|
||||||
m_antennaPath = "TX/RX";
|
m_antennaPath = "TX/RX";
|
||||||
m_clockSource = "internal";
|
m_clockSource = "internal";
|
||||||
@ -58,6 +59,7 @@ QByteArray USRPOutputSettings::serialize() const
|
|||||||
s.writeString(10, m_reverseAPIAddress);
|
s.writeString(10, m_reverseAPIAddress);
|
||||||
s.writeU32(11, m_reverseAPIPort);
|
s.writeU32(11, m_reverseAPIPort);
|
||||||
s.writeU32(12, m_reverseAPIDeviceIndex);
|
s.writeU32(12, m_reverseAPIDeviceIndex);
|
||||||
|
s.writeS32(13, m_loOffset);
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
@ -97,6 +99,7 @@ bool USRPOutputSettings::deserialize(const QByteArray& data)
|
|||||||
|
|
||||||
d.readU32(12, &uintval, 0);
|
d.readU32(12, &uintval, 0);
|
||||||
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
|
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
|
||||||
|
d.readS32(13, &m_loOffset, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ struct USRPOutputSettings
|
|||||||
// global settings to be saved
|
// global settings to be saved
|
||||||
uint64_t m_centerFrequency;
|
uint64_t m_centerFrequency;
|
||||||
int m_devSampleRate;
|
int m_devSampleRate;
|
||||||
|
int m_loOffset;
|
||||||
// channel settings
|
// channel settings
|
||||||
uint32_t m_log2SoftInterp;
|
uint32_t m_log2SoftInterp;
|
||||||
float m_lpfBW; //!< Analog lowpass filter bandwidth (Hz)
|
float m_lpfBW; //!< Analog lowpass filter bandwidth (Hz)
|
||||||
|
@ -316,25 +316,41 @@ bool USRPInput::acquireChannel()
|
|||||||
suspendRxBuddies();
|
suspendRxBuddies();
|
||||||
suspendTxBuddies();
|
suspendTxBuddies();
|
||||||
|
|
||||||
try
|
if (m_streamId == nullptr)
|
||||||
{
|
{
|
||||||
// set up the stream
|
try
|
||||||
std::string cpu_format("sc16");
|
{
|
||||||
std::string wire_format("sc16");
|
uhd::usrp::multi_usrp::sptr usrp = m_deviceShared.m_deviceParams->getDevice();
|
||||||
std::vector<size_t> channel_nums;
|
|
||||||
channel_nums.push_back(m_deviceShared.m_channel);
|
|
||||||
|
|
||||||
uhd::stream_args_t stream_args(cpu_format, wire_format);
|
// Apply settings before creating stream
|
||||||
stream_args.channels = channel_nums;
|
// 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
|
uhd::stream_args_t stream_args(cpu_format, wire_format);
|
||||||
m_bufSamples = m_streamId->get_max_num_samps();
|
stream_args.channels = channel_nums;
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
m_streamId = m_deviceShared.m_deviceParams->getDevice()->get_rx_stream(stream_args);
|
||||||
{
|
|
||||||
qDebug() << "USRPInput::acquireChannel: exception: " << e.what();
|
// 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();
|
resumeTxBuddies();
|
||||||
@ -350,7 +366,7 @@ void USRPInput::releaseChannel()
|
|||||||
suspendRxBuddies();
|
suspendRxBuddies();
|
||||||
suspendTxBuddies();
|
suspendTxBuddies();
|
||||||
|
|
||||||
// destroy the stream - FIXME: Better way to do this?
|
// destroy the stream
|
||||||
m_streamId = nullptr;
|
m_streamId = nullptr;
|
||||||
|
|
||||||
resumeTxBuddies();
|
resumeTxBuddies();
|
||||||
@ -363,7 +379,7 @@ void USRPInput::releaseChannel()
|
|||||||
|
|
||||||
void USRPInput::init()
|
void USRPInput::init()
|
||||||
{
|
{
|
||||||
applySettings(m_settings, true);
|
applySettings(m_settings, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USRPInput::start()
|
bool USRPInput::start()
|
||||||
@ -384,8 +400,6 @@ bool USRPInput::start()
|
|||||||
m_usrpInputThread = new USRPInputThread(m_streamId, m_bufSamples, &m_sampleFifo);
|
m_usrpInputThread = new USRPInputThread(m_streamId, m_bufSamples, &m_sampleFifo);
|
||||||
qDebug("USRPInput::start: thread created");
|
qDebug("USRPInput::start: thread created");
|
||||||
|
|
||||||
applySettings(m_settings, true);
|
|
||||||
|
|
||||||
m_usrpInputThread->setLog2Decimation(m_settings.m_log2SoftDecim);
|
m_usrpInputThread->setLog2Decimation(m_settings.m_log2SoftDecim);
|
||||||
m_usrpInputThread->startWork();
|
m_usrpInputThread->startWork();
|
||||||
|
|
||||||
@ -521,7 +535,7 @@ bool USRPInput::handleMessage(const Message& message)
|
|||||||
MsgConfigureUSRP& conf = (MsgConfigureUSRP&) message;
|
MsgConfigureUSRP& conf = (MsgConfigureUSRP&) message;
|
||||||
qDebug() << "USRPInput::handleMessage: MsgConfigureUSRP";
|
qDebug() << "USRPInput::handleMessage: MsgConfigureUSRP";
|
||||||
|
|
||||||
if (!applySettings(conf.getSettings(), conf.getForce()))
|
if (!applySettings(conf.getSettings(), false, conf.getForce()))
|
||||||
{
|
{
|
||||||
qDebug("USRPInput::handleMessage config error");
|
qDebug("USRPInput::handleMessage config error");
|
||||||
}
|
}
|
||||||
@ -536,6 +550,7 @@ bool USRPInput::handleMessage(const Message& message)
|
|||||||
{
|
{
|
||||||
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();
|
||||||
}
|
}
|
||||||
else if (m_running)
|
else if (m_running)
|
||||||
{
|
{
|
||||||
@ -556,7 +571,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, true);
|
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true);
|
||||||
getMessageQueueToGUI()->push(reportToGUI);
|
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 forwardChangeOwnDSP = false;
|
||||||
bool forwardChangeRxDSP = false;
|
bool forwardChangeRxDSP = false;
|
||||||
@ -655,7 +670,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
reverseAPIKeys.append("clockSource");
|
reverseAPIKeys.append("clockSource");
|
||||||
|
|
||||||
if (m_deviceShared.m_deviceParams->getDevice())
|
if (m_deviceShared.m_deviceParams->getDevice() && (m_channelAcquired || preGetStream))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -686,7 +701,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
|
|||||||
reverseAPIKeys.append("devSampleRate");
|
reverseAPIKeys.append("devSampleRate");
|
||||||
forwardChangeAllDSP = true;
|
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);
|
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);
|
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)
|
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_transverterMode != settings.m_transverterMode)
|
||||||
|| (m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency)
|
|| (m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency)
|
||||||
|| force)
|
|| force)
|
||||||
@ -707,26 +723,34 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
|
|||||||
reverseAPIKeys.append("transverterDeltaFrequency");
|
reverseAPIKeys.append("transverterDeltaFrequency");
|
||||||
forwardChangeRxDSP = true;
|
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);
|
if (settings.m_loOffset != 0)
|
||||||
m_deviceShared.m_deviceParams->getDevice()->set_rx_freq(tune_request, m_deviceShared.m_channel);
|
{
|
||||||
|
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
|
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)
|
if ((m_settings.m_dcBlock != settings.m_dcBlock) || force)
|
||||||
{
|
{
|
||||||
reverseAPIKeys.append("dcBlock");
|
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);
|
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)
|
if ((m_settings.m_iqCorrection != settings.m_iqCorrection) || force)
|
||||||
{
|
{
|
||||||
reverseAPIKeys.append("iqCorrection");
|
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);
|
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");
|
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)
|
if (settings.m_gainMode == USRPInputSettings::GAIN_AUTO)
|
||||||
{
|
{
|
||||||
@ -754,7 +778,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
reverseAPIKeys.append("gain");
|
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);
|
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;
|
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)
|
if ((m_settings.m_lpfBW != settings.m_lpfBW) || force)
|
||||||
{
|
{
|
||||||
reverseAPIKeys.append("lpfBW");
|
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)
|
if ((m_settings.m_log2SoftDecim != settings.m_log2SoftDecim) || force)
|
||||||
@ -785,7 +814,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
reverseAPIKeys.append("antennaPath");
|
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);
|
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);
|
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)
|
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, true);
|
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true);
|
||||||
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
|
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,7 +875,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
|
|||||||
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, true);
|
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true);
|
||||||
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
|
(*itSink)->getSamplingDeviceInputMessageQueue()->push(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -867,7 +896,7 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, bool force)
|
|||||||
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, true);
|
m_settings.m_devSampleRate, m_settings.m_centerFrequency, m_settings.m_loOffset, true);
|
||||||
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
|
(*itSource)->getSamplingDeviceInputMessageQueue()->push(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ private:
|
|||||||
void resumeRxBuddies();
|
void resumeRxBuddies();
|
||||||
void suspendTxBuddies();
|
void suspendTxBuddies();
|
||||||
void resumeTxBuddies();
|
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 webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
|
||||||
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const USRPInputSettings& settings, bool force);
|
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const USRPInputSettings& settings, bool force);
|
||||||
void webapiReverseSendStartStop(bool start);
|
void webapiReverseSendStartStop(bool start);
|
||||||
|
@ -61,6 +61,9 @@ USRPInputGUI::USRPInputGUI(DeviceUISet *deviceUISet, QWidget* parent) :
|
|||||||
ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
|
ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
|
||||||
ui->sampleRate->setValueRange(8, (uint32_t) minF, (uint32_t) maxF);
|
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);
|
m_usrpInput->getLPRange(minF, maxF);
|
||||||
ui->lpf->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
ui->lpf->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
||||||
ui->lpf->setValueRange(5, (minF/1000)+1, maxF/1000);
|
ui->lpf->setValueRange(5, (minF/1000)+1, maxF/1000);
|
||||||
@ -164,6 +167,7 @@ bool USRPInputGUI::handleMessage(const Message& message)
|
|||||||
|
|
||||||
if (report.getRxElseTx()) {
|
if (report.getRxElseTx()) {
|
||||||
m_settings.m_centerFrequency = report.getCenterFrequency();
|
m_settings.m_centerFrequency = report.getCenterFrequency();
|
||||||
|
m_settings.m_loOffset = report.getLOOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
blockApplySettings(true);
|
blockApplySettings(true);
|
||||||
@ -174,7 +178,7 @@ bool USRPInputGUI::handleMessage(const Message& message)
|
|||||||
}
|
}
|
||||||
else if (DeviceUSRPShared::MsgReportClockSourceChange::match(message))
|
else if (DeviceUSRPShared::MsgReportClockSourceChange::match(message))
|
||||||
{
|
{
|
||||||
qDebug("USRPInputGUI::handleMessage MsgReportClockSourceChange");
|
qDebug("USRPInputGUI::handleMessage MsgReportClockSourceChange");
|
||||||
DeviceUSRPShared::MsgReportClockSourceChange& report = (DeviceUSRPShared::MsgReportClockSourceChange&) message;
|
DeviceUSRPShared::MsgReportClockSourceChange& report = (DeviceUSRPShared::MsgReportClockSourceChange&) message;
|
||||||
m_settings.m_clockSource = report.getClockSource();
|
m_settings.m_clockSource = report.getClockSource();
|
||||||
|
|
||||||
@ -289,6 +293,8 @@ void USRPInputGUI::updateSampleRate()
|
|||||||
} 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)));
|
||||||
}
|
}
|
||||||
|
// 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()
|
void USRPInputGUI::updateSampleRateAndFrequency()
|
||||||
@ -350,6 +356,7 @@ void USRPInputGUI::displaySettings()
|
|||||||
updateSampleRate();
|
updateSampleRate();
|
||||||
|
|
||||||
ui->lpf->setValue(m_settings.m_lpfBW / 1000);
|
ui->lpf->setValue(m_settings.m_lpfBW / 1000);
|
||||||
|
ui->loOffset->setValue(m_settings.m_loOffset / 1000);
|
||||||
|
|
||||||
ui->gain->setValue(m_settings.m_gain);
|
ui->gain->setValue(m_settings.m_gain);
|
||||||
ui->gainText->setText(tr("%1").arg(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();
|
sendSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USRPInputGUI::on_loOffset_changed(qint64 value)
|
||||||
|
{
|
||||||
|
m_settings.m_loOffset = value * 1000;
|
||||||
|
sendSettings();
|
||||||
|
}
|
||||||
|
|
||||||
void USRPInputGUI::on_gainMode_currentIndexChanged(int index)
|
void USRPInputGUI::on_gainMode_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
m_settings.m_gainMode = (USRPInputSettings::GainMode) index;
|
m_settings.m_gainMode = (USRPInputSettings::GainMode) index;
|
||||||
|
@ -89,6 +89,7 @@ private slots:
|
|||||||
void on_sampleRate_changed(quint64 value);
|
void on_sampleRate_changed(quint64 value);
|
||||||
void on_swDecim_currentIndexChanged(int index);
|
void on_swDecim_currentIndexChanged(int index);
|
||||||
void on_lpf_changed(quint64 value);
|
void on_lpf_changed(quint64 value);
|
||||||
|
void on_loOffset_changed(qint64 value);
|
||||||
void on_gainMode_currentIndexChanged(int index);
|
void on_gainMode_currentIndexChanged(int index);
|
||||||
void on_gain_valueChanged(int value);
|
void on_gain_valueChanged(int value);
|
||||||
void on_antenna_currentIndexChanged(int index);
|
void on_antenna_currentIndexChanged(int index);
|
||||||
|
@ -626,6 +626,57 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -753,6 +804,12 @@
|
|||||||
<extends>QPushButton</extends>
|
<extends>QPushButton</extends>
|
||||||
<header>gui/transverterbutton.h</header>
|
<header>gui/transverterbutton.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>ValueDialZ</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>gui/valuedialz.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||||
|
@ -28,10 +28,11 @@ void USRPInputSettings::resetToDefaults()
|
|||||||
{
|
{
|
||||||
m_centerFrequency = 435000*1000;
|
m_centerFrequency = 435000*1000;
|
||||||
m_devSampleRate = 3000000;
|
m_devSampleRate = 3000000;
|
||||||
|
m_loOffset = 0;
|
||||||
m_dcBlock = false;
|
m_dcBlock = false;
|
||||||
m_iqCorrection = false;
|
m_iqCorrection = false;
|
||||||
m_log2SoftDecim = 0;
|
m_log2SoftDecim = 0;
|
||||||
m_lpfBW = 5.5e6f;
|
m_lpfBW = 10e6f;
|
||||||
m_gain = 50;
|
m_gain = 50;
|
||||||
m_antennaPath = "TX/RX";
|
m_antennaPath = "TX/RX";
|
||||||
m_gainMode = GAIN_AUTO;
|
m_gainMode = GAIN_AUTO;
|
||||||
@ -63,6 +64,7 @@ QByteArray USRPInputSettings::serialize() const
|
|||||||
s.writeString(13, m_reverseAPIAddress);
|
s.writeString(13, m_reverseAPIAddress);
|
||||||
s.writeU32(14, m_reverseAPIPort);
|
s.writeU32(14, m_reverseAPIPort);
|
||||||
s.writeU32(15, m_reverseAPIDeviceIndex);
|
s.writeU32(15, m_reverseAPIDeviceIndex);
|
||||||
|
s.writeS32(16, m_loOffset);
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +107,7 @@ bool USRPInputSettings::deserialize(const QByteArray& data)
|
|||||||
|
|
||||||
d.readU32(15, &uintval, 0);
|
d.readU32(15, &uintval, 0);
|
||||||
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
|
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
|
||||||
|
d.readS32(16, &m_loOffset, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ struct USRPInputSettings
|
|||||||
// global settings to be saved
|
// global settings to be saved
|
||||||
uint64_t m_centerFrequency;
|
uint64_t m_centerFrequency;
|
||||||
int m_devSampleRate;
|
int m_devSampleRate;
|
||||||
|
int m_loOffset;
|
||||||
// channel settings
|
// channel settings
|
||||||
bool m_dcBlock;
|
bool m_dcBlock;
|
||||||
bool m_iqCorrection;
|
bool m_iqCorrection;
|
||||||
|
Loading…
Reference in New Issue
Block a user