diff --git a/Readme.md b/Readme.md index 664b48067..658ce9aa3 100644 --- a/Readme.md +++ b/Readme.md @@ -205,7 +205,7 @@ If you use your own location for libmirisdr-4 install directory you need to spec

XTRX

-Experimental. Compile from source. +Experimental and Linux only. Compile from source. [XTRX](https://xtrx.io) is supported through the set of [xtrx libraries](https://github.com/xtrx-sdr/images). diff --git a/devices/xtrx/devicextrx.cpp b/devices/xtrx/devicextrx.cpp index 78eaaed17..7e41e19f5 100644 --- a/devices/xtrx/devicextrx.cpp +++ b/devices/xtrx/devicextrx.cpp @@ -36,7 +36,11 @@ const uint32_t DeviceXTRX::m_pgaTbl[m_nbGains] = { }; DeviceXTRX::DeviceXTRX() : - m_dev(0) + m_dev(0), + m_inputRate(0), + m_outputRate(0), + m_masterRate(0), + m_clockGen(0) {} DeviceXTRX::~DeviceXTRX() @@ -84,3 +88,56 @@ void DeviceXTRX::getAutoGains(uint32_t autoGain, uint32_t& lnaGain, uint32_t& ti lnaGain = m_lnaTbl[value]; pgaGain = m_pgaTbl[value]; } + +double DeviceXTRX::set_samplerate(double rate, double master, bool output) +{ + if (output) + { + m_outputRate = rate; + + if (master != 0.0) { + m_masterRate = master; + } + } + else + { + m_inputRate = rate; + + if (master != 0.0) { + m_masterRate = master; + } + } + + int res = xtrx_set_samplerate(m_dev, + m_masterRate, + m_inputRate, + m_outputRate, + 0, + &m_clockGen, + &m_actualInputRate, + &m_actualOutputRate); + + if (res) + { + qCritical("DeviceXTRX::set_samplerate: Unable to set %s samplerate, m_masterRate: %f, m_inputRate: %f, m_outputRate: %f, error=%d\n", + output ? "output" : "input", m_masterRate, m_inputRate, m_outputRate, res); + return 0; + } + else + { + qDebug() << "DeviceXTRXShared::set_samplerate: sample rate set: " + << "output: "<< output + << "m_masterRate: " << m_masterRate + << "m_inputRate: " << m_inputRate + << "m_outputRate: " << m_outputRate + << "m_clockGen: " << m_clockGen + << "m_actualInputRate: " << m_actualInputRate + << "m_actualOutputRate: " << m_actualOutputRate; + } + + if (output) { + return m_outputRate; + } + + return m_inputRate; +} \ No newline at end of file diff --git a/devices/xtrx/devicextrx.h b/devices/xtrx/devicextrx.h index b34bc522a..8c2d921b4 100644 --- a/devices/xtrx/devicextrx.h +++ b/devices/xtrx/devicextrx.h @@ -32,6 +32,11 @@ public: bool open(const char* deviceStr); void close(); struct xtrx_dev *getDevice() { return m_dev; } + double set_samplerate(double rate, double master, bool output); + double getMasterRate() const { return m_masterRate; } + double getClockGen() const { return m_clockGen; } + double getActualInputRate() const { return m_actualInputRate; } + double getActualOutputRate() const { return m_actualOutputRate; } static void getAutoGains(uint32_t autoGain, uint32_t& lnaGain, uint32_t& tiaGain, uint32_t& pgaGain); static const uint32_t m_nbGains = 74; @@ -39,6 +44,12 @@ public: private: struct xtrx_dev *m_dev; //!< device handle + double m_inputRate; + double m_outputRate; + double m_masterRate; + double m_clockGen; + double m_actualInputRate; + double m_actualOutputRate; static const uint32_t m_lnaTbl[m_nbGains]; static const uint32_t m_pgaTbl[m_nbGains]; diff --git a/devices/xtrx/devicextrxshared.cpp b/devices/xtrx/devicextrxshared.cpp index 6057a9ff2..e9c5f1e98 100644 --- a/devices/xtrx/devicextrxshared.cpp +++ b/devices/xtrx/devicextrxshared.cpp @@ -31,9 +31,7 @@ DeviceXTRXShared::DeviceXTRXShared() : m_channel(-1), m_source(0), m_sink(0), - m_inputRate(0), - m_outputRate(0), - m_masterRate(0), + m_thread(0), m_threadWasRunning(false) {} @@ -41,63 +39,6 @@ DeviceXTRXShared::DeviceXTRXShared() : DeviceXTRXShared::~DeviceXTRXShared() {} -double DeviceXTRXShared::set_samplerate(double rate, double master, bool output) -{ - if (output) - { - m_outputRate = rate; - - if (master != 0.0) { - m_masterRate = master; - } - } - else - { - m_inputRate = rate; - - if (master != 0.0) { - m_masterRate = master; - } - } - - double actualcgen; - double actualrx; - double actualtx; - - int res = xtrx_set_samplerate(m_dev->getDevice(), - m_masterRate, - m_inputRate, - m_outputRate, - 0, - &actualcgen, - &actualrx, - &actualtx); - - if (res) - { - qCritical("DeviceXTRXShared::set_samplerate: Unable to set %s samplerate, m_masterRate: %f, m_inputRate: %f, m_outputRate: %f, error=%d\n", - output ? "output" : "input", m_masterRate, m_inputRate, m_outputRate, res); - return 0; - } - else - { - qDebug() << "DeviceXTRXShared::set_samplerate: sample rate set: " - << "output: "<< output - << "m_masterRate: " << m_masterRate - << "m_inputRate: " << m_inputRate - << "m_outputRate: " << m_outputRate - << "actualcgen: " << actualcgen - << "actualrx: " << actualrx - << "actualtx: " << actualtx; - } - - if (output) { - return m_outputRate; - } - - return m_inputRate; -} - double DeviceXTRXShared::get_board_temperature() { uint64_t val = 0; diff --git a/devices/xtrx/devicextrxshared.h b/devices/xtrx/devicextrxshared.h index 37dde9d2f..63c01b01c 100644 --- a/devices/xtrx/devicextrxshared.h +++ b/devices/xtrx/devicextrxshared.h @@ -136,9 +136,7 @@ public: int m_channel; //!< allocated channel (-1 if none) XTRXInput *m_source; XTRXOutput *m_sink; - double m_inputRate; - double m_outputRate; - double m_masterRate; + ThreadInterface *m_thread; //!< holds the thread address if started else 0 bool m_threadWasRunning; //!< flag to know if thread needs to be resumed after suspend @@ -148,7 +146,6 @@ public: DeviceXTRXShared(); ~DeviceXTRXShared(); - double set_samplerate(double rate, double master, bool output); double get_board_temperature(); bool get_gps_status(); }; diff --git a/plugins/samplesink/xtrxoutput/readme.md b/plugins/samplesink/xtrxoutput/readme.md index e225f5ae6..04d320999 100644 --- a/plugins/samplesink/xtrxoutput/readme.md +++ b/plugins/samplesink/xtrxoutput/readme.md @@ -2,6 +2,8 @@

Introduction

+⚠ Support is experimental and for Linux only. You have to compile it from source. + This output sample sink plugin sends its samples to a [XTRX device](https://xtrx.io). XTRX is a 2x2 MIMO device so it has two transmitting channels that can run concurrently. To activate the second channel when the first is already active just open a new sink tab in the main window (Devices -> Add sink device) and select the same LimeSDR device. @@ -24,12 +26,12 @@ If libraries are installed in a custom place like `/opt/install/xtrx-images` add

1: Start/Stop

-Device start / stop button. +Device start / stop button. - Blue triangle icon: device is ready and can be started - Green square icon: device is running and can be stopped - Magenta (or pink) square icon: an error occurred. In the case the device was accidentally disconnected you may click on the icon to stop, plug back in, check the source on the sampling devices control panel and start again. - +

2: DAC sample rate

This is the sample rate at which the DAC runs in kS/s (k) or MS/s (M) after hardware interpolation (9). Thus this is the host to device sample rate (11) multiplied by the hardware interpolation factor (9). Please note that a hardware decimation of 4 is required for the device to work properly. @@ -57,7 +59,7 @@ Use this button to activate/deactivate the TSP NCO. The LMS7002M chip has an ind This is the frequency shift applied when the NCO is engaged thus the actual LO frequency is the center frequency of transmission minus this value. Use the thumbwheels to adjust frequency as done with the LO (1.1). Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2. The boundaries are dynamically calculated from the LO center frequency, sample rate and hardware interpolation factor. -☞ In the LMS7002M TSP block the NCO sits after the interpolator (see Fig.14 of the [datasheet](http://www.limemicro.com/wp-content/uploads/2015/09/LMS7002M-Data-Sheet-v2.8.0.pdf) p.7) so it runs at the actual DAC rate. Hence the NCO limits are calculated as +/- half the device to host sample rate multiplied by the hardware interpolation factor. For example with a 4 MS/s device to host sample rate (10) and a hardware interpolation of 16 (9) you have +/- 32 MHz span around the LO for the NCO. In this example you can tune all HF frequencies with the center frequency set at its lowest (30 MHz). +☞ In the LMS7002M TSP block the NCO sits after the interpolator (see Fig.14 of the [datasheet](http://www.limemicro.com/wp-content/uploads/2015/09/LMS7002M-Data-Sheet-v2.8.0.pdf) p.7) so it runs at the actual DAC rate. Hence the NCO limits are calculated as +/- half the device to host sample rate multiplied by the hardware interpolation factor. For example with a 4 MS/s device to host sample rate (10) and a hardware interpolation of 16 (9) you have +/- 32 MHz span around the LO for the NCO. In this example you can tune all HF frequencies with the center frequency set at its lowest (30 MHz).

8: External clock control

@@ -78,7 +80,7 @@ Use this checkbox to enable or disable the external clock input

8.3: Confirm changes

Use the "OK" button to confirm your changes - +

8.4: Dismiss changes

Use the "Cancel" button to dismiss your changes @@ -89,6 +91,8 @@ The TSP block in the LMS7002M hardware has an interpolation chain that acts on b Thus the actual sample rate of the DAC is the stream sample rate (11) multiplied by this factor. In the screenshot example this yields a 12.288 MS/s rate at the DAC (3.072 * 4). +The first position in the combo is marked as "A". This is because interpolation by 1 is not implemented and instead an automatic interpolation factor is applied. The DAC rate display is updated automatically and siblings are updated with the actual DAC and hardware interpolation factor. +

10: Software interpolation factor

The I/Q stream from the baseband is upsampled by a power of two by software inside the plugin before being sent to the LimeSDR device. Possible values are increasing powers of two: 1 (no interpolation), 2, 4, 8, 16, 32. @@ -123,7 +127,7 @@ This label turns green when status can be obtained from the current stream. Usua

17: GPSDO lock indicator

This label turns green when the GPS used for the GPSDO is locked. - +

18: Stream global (all Tx) throughput in MB/s

This is the stream throughput in MB/s and is usually about 3 times the sample rate for a single stream and 6 times for a dual Tx stream. This is due to the fact that 12 bits samples are used and although they are represented as 16 bit values only 12 bits travel on the USB link. diff --git a/plugins/samplesink/xtrxoutput/xtrxoutput.cpp b/plugins/samplesink/xtrxoutput/xtrxoutput.cpp index 0103ce1ad..6e4e40b10 100644 --- a/plugins/samplesink/xtrxoutput/xtrxoutput.cpp +++ b/plugins/samplesink/xtrxoutput/xtrxoutput.cpp @@ -41,6 +41,7 @@ MESSAGE_CLASS_DEFINITION(XTRXOutput::MsgConfigureXTRX, Message) MESSAGE_CLASS_DEFINITION(XTRXOutput::MsgGetStreamInfo, Message) MESSAGE_CLASS_DEFINITION(XTRXOutput::MsgGetDeviceInfo, Message) +MESSAGE_CLASS_DEFINITION(XTRXOutput::MsgReportClockGenChange, Message) MESSAGE_CLASS_DEFINITION(XTRXOutput::MsgReportStreamInfo, Message) MESSAGE_CLASS_DEFINITION(XTRXOutput::MsgStartStop, Message) @@ -492,9 +493,45 @@ const QString& XTRXOutput::getDeviceDescription() const int XTRXOutput::getSampleRate() const { double rate = m_settings.m_devSampleRate; + + if (m_deviceShared.m_dev) { + rate = m_deviceShared.m_dev->getActualOutputRate(); + } + return (int)((rate / (1<getActualOutputRate(); + } + + return devSampleRate; +} + +uint32_t XTRXOutput::getLog2HardInterp() const +{ + uint32_t log2HardInterp = m_settings.m_log2HardInterp; + + if (m_deviceShared.m_dev && (m_deviceShared.m_dev->getActualOutputRate() != 0.0)) { + log2HardInterp = log2(m_deviceShared.m_dev->getClockGen() / m_deviceShared.m_dev->getActualOutputRate() / 4); + } + + return log2HardInterp; +} + +double XTRXOutput::getClockGen() const +{ + if (m_deviceShared.m_dev) { + return m_deviceShared.m_dev->getClockGen(); + } else { + return 0.0; + } +} + quint64 XTRXOutput::getCenterFrequency() const { return m_settings.m_centerFrequency + (m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0); @@ -573,13 +610,13 @@ bool XTRXOutput::handleMessage(const Message& message) } else { - m_settings.m_devSampleRate = m_deviceShared.m_inputRate; - m_settings.m_log2HardInterp = log2(m_deviceShared.m_masterRate / m_deviceShared.m_inputRate / 4); + m_settings.m_devSampleRate = m_deviceShared.m_dev->getActualOutputRate(); + m_settings.m_log2HardInterp = getLog2HardInterp(); qDebug() << "XTRXOutput::handleMessage: MsgReportBuddyChange:" - << " host_Hz: " << m_deviceShared.m_inputRate - << " rf_Hz: " << m_deviceShared.m_masterRate / 4 - << " m_log2HardDecim: " << m_settings.m_log2HardInterp; + << " host_Hz: " << m_deviceShared.m_dev->getActualOutputRate() + << " dac_Hz: " << m_deviceShared.m_dev->getClockGen() / 4 + << " m_log2HardInterp: " << m_settings.m_log2HardInterp; } if (m_settings.m_ncoEnable) // need to reset NCO after sample rate change @@ -917,9 +954,9 @@ bool XTRXOutput::applySettings(const XTRXOutputSettings& settings, bool force, b double master = (settings.m_log2HardInterp == 0) ? 0 : (settings.m_devSampleRate * 4 * (1 << settings.m_log2HardInterp)); - if (m_deviceShared.set_samplerate(settings.m_devSampleRate, - master, //(settings.m_devSampleRate<set_samplerate(settings.m_devSampleRate, + master, //(settings.m_devSampleRate<getActualOutputRate(), + 1 << getLog2HardInterp()); } resumeRxThread(); @@ -1005,11 +1043,15 @@ bool XTRXOutput::applySettings(const XTRXOutputSettings& settings, bool force, b int ncoShift = m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0; // send to self first - DSPSignalNotification *notif = new DSPSignalNotification( - m_settings.m_devSampleRate/(1<getDeviceEngineInputMessageQueue()->push(notif); + if (getMessageQueueToGUI()) + { + MsgReportClockGenChange *report = MsgReportClockGenChange::create(); + getMessageQueueToGUI()->push(report); + } + // send to source buddies const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); std::vector::const_iterator itSource = sourceBuddies.begin(); @@ -1017,7 +1059,7 @@ bool XTRXOutput::applySettings(const XTRXOutputSettings& settings, bool force, b for (; itSource != sourceBuddies.end(); ++itSource) { DeviceXTRXShared::MsgReportBuddyChange *report = DeviceXTRXShared::MsgReportBuddyChange::create( - m_settings.m_devSampleRate, m_settings.m_log2HardInterp, m_settings.m_centerFrequency, true); + getDevSampleRate(), getLog2HardInterp(), m_settings.m_centerFrequency, true); (*itSource)->getSampleSourceInputMessageQueue()->push(report); } @@ -1028,7 +1070,7 @@ bool XTRXOutput::applySettings(const XTRXOutputSettings& settings, bool force, b for (; itSink != sinkBuddies.end(); ++itSink) { DeviceXTRXShared::MsgReportBuddyChange *report = DeviceXTRXShared::MsgReportBuddyChange::create( - m_settings.m_devSampleRate, m_settings.m_log2HardInterp, m_settings.m_centerFrequency, true); + getDevSampleRate(), getLog2HardInterp(), m_settings.m_centerFrequency, true); (*itSink)->getSampleSinkInputMessageQueue()->push(report); } } @@ -1036,13 +1078,18 @@ bool XTRXOutput::applySettings(const XTRXOutputSettings& settings, bool force, b { qDebug("XTRXOutput::applySettings: forward change to Tx buddies"); - int sampleRate = m_settings.m_devSampleRate/(1<getDeviceEngineInputMessageQueue()->push(notif); + if (getMessageQueueToGUI()) + { + MsgReportClockGenChange *report = MsgReportClockGenChange::create(); + getMessageQueueToGUI()->push(report); + } + // send to sink buddies const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); std::vector::const_iterator itSink = sinkBuddies.begin(); @@ -1050,7 +1097,7 @@ bool XTRXOutput::applySettings(const XTRXOutputSettings& settings, bool force, b for (; itSink != sinkBuddies.end(); ++itSink) { DeviceXTRXShared::MsgReportBuddyChange *report = DeviceXTRXShared::MsgReportBuddyChange::create( - m_settings.m_devSampleRate, m_settings.m_log2HardInterp, m_settings.m_centerFrequency, true); + getDevSampleRate(), getLog2HardInterp(), m_settings.m_centerFrequency, true); (*itSink)->getSampleSinkInputMessageQueue()->push(report); } } @@ -1058,10 +1105,16 @@ bool XTRXOutput::applySettings(const XTRXOutputSettings& settings, bool force, b { qDebug("XTRXOutput::applySettings: forward change to self only"); - int sampleRate = m_settings.m_devSampleRate/(1<getDeviceEngineInputMessageQueue()->push(notif); + + if (getMessageQueueToGUI()) + { + MsgReportClockGenChange *report = MsgReportClockGenChange::create(); + getMessageQueueToGUI()->push(report); + } } if (forwardClockSource) @@ -1090,8 +1143,10 @@ bool XTRXOutput::applySettings(const XTRXOutputSettings& settings, bool force, b } qDebug() << "XTRXOutput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz" - << " device stream sample rate: " << m_settings.m_devSampleRate << "S/s" - << " sample rate with soft interpolation: " << m_settings.m_devSampleRate/(1<getDevSampleRate(); + + blockApplySettings(true); + displaySettings(); + blockApplySettings(false); + + return true; + } else if (XTRXOutput::MsgReportStreamInfo::match(message)) { XTRXOutput::MsgReportStreamInfo& report = (XTRXOutput::MsgReportStreamInfo&) message; @@ -243,7 +253,7 @@ void XTRXOutputGUI::handleInputMessages() void XTRXOutputGUI::updateDACRate() { - uint32_t dacRate = m_settings.m_devSampleRate * (1<getClockGen() / 4; if (dacRate < 100000000) { ui->dacRateLabel->setText(tr("%1k").arg(QString::number(dacRate / 1000.0f, 'g', 5))); diff --git a/plugins/samplesink/xtrxoutput/xtrxoutputgui.ui b/plugins/samplesink/xtrxoutput/xtrxoutputgui.ui index b7b14da08..6b2492b4e 100644 --- a/plugins/samplesink/xtrxoutput/xtrxoutputgui.ui +++ b/plugins/samplesink/xtrxoutput/xtrxoutputgui.ui @@ -328,7 +328,7 @@ - 1 + A diff --git a/plugins/samplesource/xtrxinput/readme.md b/plugins/samplesource/xtrxinput/readme.md index 8963ba313..58db4df7d 100644 --- a/plugins/samplesource/xtrxinput/readme.md +++ b/plugins/samplesource/xtrxinput/readme.md @@ -2,6 +2,8 @@

Introduction

+⚠ Support is experimental and for Linux only. You have to compile it from source. + This input sample source plugin gets its samples from a [XTRX device](https://xtrx.io). XTRX is a 2x2 MIMO device so it has two receiving channels that can run concurrently. To activate the second channel when the first is already active just open a new source tab in the main window (Devices -> Add source device) and select the same LimeSDR device. You may need to change frequency back and forth in case reception is not working properly. @@ -30,12 +32,12 @@ This is the center frequency of reception in kHz.

1.2: Start/Stop

-Device start / stop button. +Device start / stop button. - Blue triangle icon: device is ready and can be started - Green square icon: device is running and can be stopped - Magenta (or pink) square icon: an error occurred. In the case the device was accidentally disconnected you may click on the icon to stop, plug back in, check the source on the sampling devices control panel and start again. - +

1.3: Record

Record baseband I/Q stream toggle button @@ -48,7 +50,7 @@ This is the sample rate at which the ADC runs in kS/s (k) or MS/s (M) before har

1.5: Stream sample rate

-Baseband I/Q sample rate in kS/s. This is the device to host sample rate (5) divided by the software decimation factor (4). +Baseband I/Q sample rate in kS/s. This is the device to host sample rate (5) divided by the software decimation factor (4).

1.6: Channel number

@@ -68,7 +70,7 @@ Use this button to activate/deactivate the TSP NCO. The LMS7002M chip has an ind This is the frequency shift applied when the NCO is engaged thus the actual LO frequency is the center frequency of reception minus this value. Use the thumbwheels to adjust frequency as done with the LO (1.1). Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2. The boundaries are dynamically calculated from the LO center frequency, sample rate and hardware decimation factor. -☞ In the LMS7002M TSP block the NCO sits before the decimator (see Fig.14 of the [datasheet](http://www.limemicro.com/wp-content/uploads/2015/09/LMS7002M-Data-Sheet-v2.8.0.pdf) p.7) so it runs at the actual ADC rate. Hence the NCO limits are calculated as +/- half the device to host sample rate multiplied by the hardware decimation factor. For example with a 4 MS/s device to host sample rate (5) and a hardware decimation of 16 (3) you have +/- 32 MHz span around the LO for the NCO. In this example you can tune all HF frequencies with the center frequency set at its lowest (30 MHz). +☞ In the LMS7002M TSP block the NCO sits before the decimator (see Fig.14 of the [datasheet](http://www.limemicro.com/wp-content/uploads/2015/09/LMS7002M-Data-Sheet-v2.8.0.pdf) p.7) so it runs at the actual ADC rate. Hence the NCO limits are calculated as +/- half the device to host sample rate multiplied by the hardware decimation factor. For example with a 4 MS/s device to host sample rate (5) and a hardware decimation of 16 (3) you have +/- 32 MHz span around the LO for the NCO. In this example you can tune all HF frequencies with the center frequency set at its lowest (30 MHz).

2.3: DC component auto correction

@@ -97,16 +99,18 @@ Use this checkbox to enable or disable the external clock input
2.6.3: Confirm changes
Use the "OK" button to confirm your changes - +
2.6.4: Dismiss changes
Use the "Cancel" button to dismiss your changes - +

3: LMS7002M hardware decimation factor

The TSP block in the LMS7002M hardware has a decimation chain that acts on both Rx channels. It is composed of 5 halfband decimation stages and therefore can achieve decimation between 1 (no decimation) and 32 in increasing powers of 2: 1, 2, 4, 8, 16, 32. -Thus the actual sample rate of the ADC is the stream sample rate (5) multiplied by this factor. +Thus the actual sample rate of the ADC is the stream sample rate (5) multiplied by this factor. + +The first position in the combo is marked as "A". This is because decimation by 1 is not implemented and instead an automatic decimation factor is applied. The ADC rate display is updated automatically and siblings are updated with the actual ADC and hardware decimation factor.

4: Software decimation factor

@@ -158,7 +162,7 @@ Use this combo box to select the antenna input: - **Lo**: Selects the low frequency input (700 to 900 MHz nominally) - **Hi**: Selects the high frequency input (2 to 2.6 GHz) - +

10: Stream status indicator

This label turns green when status can be obtained from the current stream. Usually this means that the stream is up and running but not necessarily streaming data. The various status elements appear next on the same line (12) diff --git a/plugins/samplesource/xtrxinput/xtrxinput.cpp b/plugins/samplesource/xtrxinput/xtrxinput.cpp index 0ca83e11b..2b361d321 100644 --- a/plugins/samplesource/xtrxinput/xtrxinput.cpp +++ b/plugins/samplesource/xtrxinput/xtrxinput.cpp @@ -42,6 +42,7 @@ MESSAGE_CLASS_DEFINITION(XTRXInput::MsgConfigureXTRX, Message) MESSAGE_CLASS_DEFINITION(XTRXInput::MsgGetStreamInfo, Message) MESSAGE_CLASS_DEFINITION(XTRXInput::MsgGetDeviceInfo, Message) +MESSAGE_CLASS_DEFINITION(XTRXInput::MsgReportClockGenChange, Message) MESSAGE_CLASS_DEFINITION(XTRXInput::MsgReportStreamInfo, Message) MESSAGE_CLASS_DEFINITION(XTRXInput::MsgFileRecord, Message) MESSAGE_CLASS_DEFINITION(XTRXInput::MsgStartStop, Message) @@ -507,9 +508,45 @@ const QString& XTRXInput::getDeviceDescription() const int XTRXInput::getSampleRate() const { double rate = m_settings.m_devSampleRate; + + if (m_deviceShared.m_dev) { + rate = m_deviceShared.m_dev->getActualInputRate(); + } + return (int)((rate / (1<getActualInputRate(); + } + + return devSampleRate; +} + +uint32_t XTRXInput::getLog2HardDecim() const +{ + uint32_t log2HardDecim = m_settings.m_log2HardDecim; + + if (m_deviceShared.m_dev && (m_deviceShared.m_dev->getActualInputRate() != 0.0)) { + log2HardDecim = log2(m_deviceShared.m_dev->getClockGen() / m_deviceShared.m_dev->getActualInputRate() / 4); + } + + return log2HardDecim; +} + +double XTRXInput::getClockGen() const +{ + if (m_deviceShared.m_dev) { + return m_deviceShared.m_dev->getClockGen(); + } else { + return 0.0; + } +} + quint64 XTRXInput::getCenterFrequency() const { return m_settings.m_centerFrequency + (m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0); @@ -588,12 +625,12 @@ bool XTRXInput::handleMessage(const Message& message) } else { - m_settings.m_devSampleRate = m_deviceShared.m_inputRate; - m_settings.m_log2HardDecim = log2(m_deviceShared.m_masterRate / m_deviceShared.m_inputRate / 4); + m_settings.m_devSampleRate = m_deviceShared.m_dev->getActualInputRate(); + m_settings.m_log2HardDecim = getLog2HardDecim(); qDebug() << "XTRXInput::handleMessage: MsgReportBuddyChange:" - << " host_Hz: " << m_deviceShared.m_inputRate - << " rf_Hz: " << m_deviceShared.m_masterRate / 4 + << " host_Hz: " << m_deviceShared.m_dev->getActualInputRate() + << " adc_Hz: " << m_deviceShared.m_dev->getClockGen() / 4 << " m_log2HardDecim: " << m_settings.m_log2HardDecim; } @@ -1057,9 +1094,9 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo double master = (settings.m_log2HardDecim == 0) ? 0 : (settings.m_devSampleRate * 4 * (1 << settings.m_log2HardDecim)); - if (m_deviceShared.set_samplerate(settings.m_devSampleRate, - master, //(settings.m_devSampleRate<set_samplerate(settings.m_devSampleRate, + master, //(settings.m_devSampleRate<getActualInputRate(), + 1 << getLog2HardDecim()); } resumeTxThread(); @@ -1162,11 +1200,15 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo int ncoShift = m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0; // send to self first - DSPSignalNotification *notif = new DSPSignalNotification( - m_settings.m_devSampleRate/(1<getDeviceEngineInputMessageQueue()->push(notif); + if (getMessageQueueToGUI()) + { + MsgReportClockGenChange *report = MsgReportClockGenChange::create(); + getMessageQueueToGUI()->push(report); + } + // send to source buddies const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); std::vector::const_iterator itSource = sourceBuddies.begin(); @@ -1174,7 +1216,7 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo for (; itSource != sourceBuddies.end(); ++itSource) { DeviceXTRXShared::MsgReportBuddyChange *report = DeviceXTRXShared::MsgReportBuddyChange::create( - m_settings.m_devSampleRate, m_settings.m_log2HardDecim, m_settings.m_centerFrequency, true); + getDevSampleRate(), getLog2HardDecim(), m_settings.m_centerFrequency, true); (*itSource)->getSampleSourceInputMessageQueue()->push(report); } @@ -1185,7 +1227,7 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo for (; itSink != sinkBuddies.end(); ++itSink) { DeviceXTRXShared::MsgReportBuddyChange *report = DeviceXTRXShared::MsgReportBuddyChange::create( - m_settings.m_devSampleRate, m_settings.m_log2HardDecim, m_settings.m_centerFrequency, true); + getDevSampleRate(), getLog2HardDecim(), m_settings.m_centerFrequency, true); (*itSink)->getSampleSinkInputMessageQueue()->push(report); } } @@ -1193,13 +1235,18 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo { qDebug("XTRXInput::applySettings: forward change to Rx buddies"); - int sampleRate = m_settings.m_devSampleRate/(1<getDeviceEngineInputMessageQueue()->push(notif); + if (getMessageQueueToGUI()) + { + MsgReportClockGenChange *report = MsgReportClockGenChange::create(); + getMessageQueueToGUI()->push(report); + } + // send to source buddies const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); std::vector::const_iterator itSource = sourceBuddies.begin(); @@ -1207,7 +1254,7 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo for (; itSource != sourceBuddies.end(); ++itSource) { DeviceXTRXShared::MsgReportBuddyChange *report = DeviceXTRXShared::MsgReportBuddyChange::create( - m_settings.m_devSampleRate, m_settings.m_log2HardDecim, m_settings.m_centerFrequency, true); + getDevSampleRate(), getLog2HardDecim(), m_settings.m_centerFrequency, true); (*itSource)->getSampleSourceInputMessageQueue()->push(report); } } @@ -1215,11 +1262,17 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo { qDebug("XTRXInput::applySettings: forward change to self only"); - int sampleRate = m_settings.m_devSampleRate/(1<handleMessage(*notif); // forward to file sink m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); + + if (getMessageQueueToGUI()) + { + MsgReportClockGenChange *report = MsgReportClockGenChange::create(); + getMessageQueueToGUI()->push(report); + } } if (forwardClockSource) @@ -1248,8 +1301,10 @@ bool XTRXInput::applySettings(const XTRXInputSettings& settings, bool force, boo } qDebug() << "XTRXInput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz" - << " device stream sample rate: " << m_settings.m_devSampleRate << "S/s" - << " sample rate with soft decimation: " << m_settings.m_devSampleRate/(1<getDevSampleRate(); + + blockApplySettings(true); + displaySettings(); + blockApplySettings(false); + + return true; + } else if (XTRXInput::MsgReportStreamInfo::match(message)) { XTRXInput::MsgReportStreamInfo& report = (XTRXInput::MsgReportStreamInfo&) message; @@ -245,7 +255,7 @@ void XTRXInputGUI::handleInputMessages() void XTRXInputGUI::updateADCRate() { - uint32_t adcRate = m_settings.m_devSampleRate * (1<getClockGen() / 4; if (adcRate < 100000000) { ui->adcRateLabel->setText(tr("%1k").arg(QString::number(adcRate / 1000.0f, 'g', 5))); diff --git a/plugins/samplesource/xtrxinput/xtrxinputgui.ui b/plugins/samplesource/xtrxinput/xtrxinputgui.ui index 4ea9dd7d4..fd49e12f9 100644 --- a/plugins/samplesource/xtrxinput/xtrxinputgui.ui +++ b/plugins/samplesource/xtrxinput/xtrxinputgui.ui @@ -29,7 +29,7 @@ - LimeSDR Input + XTRX Input @@ -363,7 +363,7 @@ - 1 + A