From 2ec8270e9963739f474170396fa6895816d62306 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sat, 4 Nov 2017 02:18:16 +0100 Subject: [PATCH] LimeSDR: handle clock source change in source and sink --- devices/limesdr/devicelimesdr.cpp | 30 +++++++++ devices/limesdr/devicelimesdr.h | 2 + devices/limesdr/devicelimesdrshared.cpp | 1 + devices/limesdr/devicelimesdrshared.h | 29 +++++++++ .../limesdroutput/limesdroutput.cpp | 65 ++++++++++++++++++- .../limesdroutput/limesdroutputsettings.cpp | 6 ++ .../limesdroutput/limesdroutputsettings.h | 2 + .../limesdrinput/limesdrinput.cpp | 65 ++++++++++++++++++- .../limesdrinput/limesdrinputsettings.cpp | 6 ++ .../limesdrinput/limesdrinputsettings.h | 2 + 10 files changed, 206 insertions(+), 2 deletions(-) diff --git a/devices/limesdr/devicelimesdr.cpp b/devices/limesdr/devicelimesdr.cpp index 88e0e69d4..659e7fad1 100644 --- a/devices/limesdr/devicelimesdr.cpp +++ b/devices/limesdr/devicelimesdr.cpp @@ -344,3 +344,33 @@ bool DeviceLimeSDR::setTxAntennaPath(lms_device_t *device, std::size_t chan, int return true; } + +bool DeviceLimeSDR::setClockSource(lms_device_t *device, bool extClock, uint32_t extClockFrequency) +{ + if (extClock) + { + if (LMS_SetClockFreq(device, LMS_CLOCK_EXTREF, (float) extClockFrequency) < 0) + { + fprintf(stderr, "DeviceLimeSDR::setClockSource: cannot set to external\n"); + return false; + } + } + else + { + uint16_t vcoTrimValue; + + if (LMS_VCTCXORead(device, &vcoTrimValue)) + { + fprintf(stderr, "DeviceLimeSDR::setClockSource: cannot read VCTXO trim value\n"); + return false; + } + + if (LMS_VCTCXOWrite(device, vcoTrimValue)) + { + fprintf(stderr, "DeviceLimeSDR::setClockSource: cannot write VCTXO trim value\n"); + return false; + } + } + + return true; +} diff --git a/devices/limesdr/devicelimesdr.h b/devices/limesdr/devicelimesdr.h index 4cc34d177..01421277f 100644 --- a/devices/limesdr/devicelimesdr.h +++ b/devices/limesdr/devicelimesdr.h @@ -51,6 +51,8 @@ public: static bool setRxAntennaPath(lms_device_t *device, std::size_t chan, int path); /** Set Tx antenna path **/ static bool setTxAntennaPath(lms_device_t *device, std::size_t chan, int path); + /** Set clock source and external clock frequency if required */ + static bool setClockSource(lms_device_t *device, bool extClock, uint32_t extClockFrequency); }; #endif /* DEVICES_LIMESDR_DEVICELIMESDR_H_ */ diff --git a/devices/limesdr/devicelimesdrshared.cpp b/devices/limesdr/devicelimesdrshared.cpp index 554e58f89..ba9f4d6f0 100644 --- a/devices/limesdr/devicelimesdrshared.cpp +++ b/devices/limesdr/devicelimesdrshared.cpp @@ -17,6 +17,7 @@ #include "devicelimesdrshared.h" MESSAGE_CLASS_DEFINITION(DeviceLimeSDRShared::MsgReportBuddyChange, Message) +MESSAGE_CLASS_DEFINITION(DeviceLimeSDRShared::MsgReportClockSourceChange, Message) MESSAGE_CLASS_DEFINITION(DeviceLimeSDRShared::MsgReportDeviceInfo, Message) const float DeviceLimeSDRShared::m_sampleFifoLengthInSeconds = 0.25; diff --git a/devices/limesdr/devicelimesdrshared.h b/devices/limesdr/devicelimesdrshared.h index 4cdf81562..d23894399 100644 --- a/devices/limesdr/devicelimesdrshared.h +++ b/devices/limesdr/devicelimesdrshared.h @@ -68,6 +68,35 @@ public: { } }; + class MsgReportClockSourceChange : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getExtClock() const { return m_extClock; } + uint32_t getExtClockFeq() const { return m_extClockFreq; } + + static MsgReportClockSourceChange* create( + bool extClock, + uint32_t m_extClockFreq) + { + return new MsgReportClockSourceChange( + extClock, + m_extClockFreq); + } + + private: + bool m_extClock; //!< True if external clock source + uint32_t m_extClockFreq; //!< Frequency (Hz) of external clock source + + MsgReportClockSourceChange( + bool extClock, + uint32_t m_extClockFreq) : + Message(), + m_extClock(extClock), + m_extClockFreq(m_extClockFreq) + { } + }; + class MsgReportDeviceInfo : public Message { MESSAGE_CLASS_DECLARATION diff --git a/plugins/samplesink/limesdroutput/limesdroutput.cpp b/plugins/samplesink/limesdroutput/limesdroutput.cpp index 6b110e6aa..e43e5edef 100644 --- a/plugins/samplesink/limesdroutput/limesdroutput.cpp +++ b/plugins/samplesink/limesdroutput/limesdroutput.cpp @@ -519,6 +519,19 @@ bool LimeSDROutput::handleMessage(const Message& message) return true; } + else if (DeviceLimeSDRShared::MsgReportClockSourceChange::match(message)) + { + DeviceLimeSDRShared::MsgReportClockSourceChange& report = (DeviceLimeSDRShared::MsgReportClockSourceChange&) message; + + m_settings.m_extClock = report.getExtClock(); + m_settings.m_extClockFreq = report.getExtClockFeq(); + + DeviceLimeSDRShared::MsgReportClockSourceChange *reportToGUI = DeviceLimeSDRShared::MsgReportClockSourceChange::create( + m_settings.m_extClock, m_settings.m_extClockFreq); + getMessageQueueToGUI()->push(reportToGUI); + + return true; + } else if (MsgGetStreamInfo::match(message)) { // qDebug() << "LimeSDROutput::handleMessage: MsgGetStreamInfo"; @@ -621,6 +634,7 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo bool forwardChangeOwnDSP = false; bool forwardChangeTxDSP = false; bool forwardChangeAllDSP = false; + bool forwardClockSource = false; bool ownThreadWasRunning = false; bool doCalibration = false; double clockGenFreq = 0.0; @@ -820,6 +834,28 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo } } + if ((m_settings.m_extClock != settings.m_extClock) || + (m_settings.m_extClockFreq != settings.m_extClockFreq) || force) + { + + if (DeviceLimeSDR::setClockSource(m_deviceShared.m_deviceParams->getDevice(), + settings.m_extClock, + settings.m_extClockFreq)) + { + forwardClockSource = true; + doCalibration = true; + qDebug("LimeSDRInput::applySettings: clock set to %s (Ext: %d Hz)", + settings.m_extClock ? "external" : "internal", + settings.m_extClockFreq); + } + else + { + qCritical("LimeSDRInput::applySettings: could not set clock to %s (Ext: %d Hz)", + settings.m_extClock ? "external" : "internal", + settings.m_extClockFreq); + } + } + m_settings = settings; double clockGenFreqAfter; @@ -933,6 +969,31 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); } + if (forwardClockSource) + { + // send to source buddies + const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); + std::vector::const_iterator itSource = sourceBuddies.begin(); + + for (; itSource != sourceBuddies.end(); ++itSource) + { + DeviceLimeSDRShared::MsgReportClockSourceChange *report = DeviceLimeSDRShared::MsgReportClockSourceChange::create( + m_settings.m_extClock, m_settings.m_extClockFreq); + (*itSource)->getSampleSourceInputMessageQueue()->push(report); + } + + // send to sink buddies + const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); + std::vector::const_iterator itSink = sinkBuddies.begin(); + + for (; itSink != sinkBuddies.end(); ++itSink) + { + DeviceLimeSDRShared::MsgReportClockSourceChange *report = DeviceLimeSDRShared::MsgReportClockSourceChange::create( + m_settings.m_extClock, m_settings.m_extClockFreq); + (*itSink)->getSampleSinkInputMessageQueue()->push(report); + } + } + qDebug() << "LimeSDROutput::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<push(reportToGUI); + + return true; + } else if (MsgGetStreamInfo::match(message)) { // qDebug() << "LimeSDRInput::handleMessage: MsgGetStreamInfo"; @@ -653,6 +666,7 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc bool forwardChangeOwnDSP = false; bool forwardChangeRxDSP = false; bool forwardChangeAllDSP = false; + bool forwardClockSource = false; bool ownThreadWasRunning = false; bool doCalibration = false; bool setAntennaAuto = false; @@ -972,6 +986,28 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc } } + if ((m_settings.m_extClock != settings.m_extClock) || + (m_settings.m_extClockFreq != settings.m_extClockFreq) || force) + { + + if (DeviceLimeSDR::setClockSource(m_deviceShared.m_deviceParams->getDevice(), + settings.m_extClock, + settings.m_extClockFreq)) + { + forwardClockSource = true; + doCalibration = true; + qDebug("LimeSDRInput::applySettings: clock set to %s (Ext: %d Hz)", + settings.m_extClock ? "external" : "internal", + settings.m_extClockFreq); + } + else + { + qCritical("LimeSDRInput::applySettings: could not set clock to %s (Ext: %d Hz)", + settings.m_extClock ? "external" : "internal", + settings.m_extClockFreq); + } + } + m_settings = settings; double clockGenFreqAfter; @@ -1086,6 +1122,31 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); } + if (forwardClockSource) + { + // send to source buddies + const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); + std::vector::const_iterator itSource = sourceBuddies.begin(); + + for (; itSource != sourceBuddies.end(); ++itSource) + { + DeviceLimeSDRShared::MsgReportClockSourceChange *report = DeviceLimeSDRShared::MsgReportClockSourceChange::create( + m_settings.m_extClock, m_settings.m_extClockFreq); + (*itSource)->getSampleSourceInputMessageQueue()->push(report); + } + + // send to sink buddies + const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); + std::vector::const_iterator itSink = sinkBuddies.begin(); + + for (; itSink != sinkBuddies.end(); ++itSink) + { + DeviceLimeSDRShared::MsgReportClockSourceChange *report = DeviceLimeSDRShared::MsgReportClockSourceChange::create( + m_settings.m_extClock, m_settings.m_extClockFreq); + (*itSink)->getSampleSinkInputMessageQueue()->push(report); + } + } + qDebug() << "LimeSDRInput::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<