mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-25 20:22:10 -05:00
LimeSDR: handle clock source change in source and sink
This commit is contained in:
parent
465416ee19
commit
2ec8270e99
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
|
||||
std::vector<DeviceSourceAPI*>::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<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
|
||||
std::vector<DeviceSinkAPI*>::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<<m_settings.m_log2SoftInterp) << "S/s"
|
||||
@ -942,7 +1003,9 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo
|
||||
<< " m_lpfFIREnable: " << m_settings.m_lpfFIREnable
|
||||
<< " m_ncoEnable: " << m_settings.m_ncoEnable
|
||||
<< " m_ncoFrequency: " << m_settings.m_ncoFrequency
|
||||
<< " m_antennaPath: " << m_settings.m_antennaPath;
|
||||
<< " m_antennaPath: " << m_settings.m_antennaPath
|
||||
<< " m_extClock: " << m_settings.m_extClock
|
||||
<< " m_extClockFreq: " << m_settings.m_extClockFreq;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ void LimeSDROutputSettings::resetToDefaults()
|
||||
m_ncoEnable = false;
|
||||
m_ncoFrequency = 0;
|
||||
m_antennaPath = PATH_RFE_NONE;
|
||||
m_extClock = false;
|
||||
m_extClockFreq = 10000000; // 10 MHz
|
||||
}
|
||||
|
||||
QByteArray LimeSDROutputSettings::serialize() const
|
||||
@ -52,6 +54,8 @@ QByteArray LimeSDROutputSettings::serialize() const
|
||||
s.writeBool(11, m_ncoEnable);
|
||||
s.writeS32(12, m_ncoFrequency);
|
||||
s.writeS32(13, (int) m_antennaPath);
|
||||
s.writeBool(14, m_extClock);
|
||||
s.writeU32(15, m_extClockFreq);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
@ -81,6 +85,8 @@ bool LimeSDROutputSettings::deserialize(const QByteArray& data)
|
||||
d.readS32(12, &m_ncoFrequency, 0);
|
||||
d.readS32(13, &intval, 0);
|
||||
m_antennaPath = (PathRFE) intval;
|
||||
d.readBool(14, &m_extClock, false);
|
||||
d.readU32(15, &m_extClockFreq, 10000000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ struct LimeSDROutputSettings
|
||||
bool m_ncoEnable; //!< Enable TSP NCO and mixing
|
||||
int m_ncoFrequency; //!< Actual NCO frequency (the resulting frequency with mixing is displayed)
|
||||
PathRFE m_antennaPath;
|
||||
bool m_extClock; //!< True if external clock source
|
||||
uint32_t m_extClockFreq; //!< Frequency (Hz) of external clock source
|
||||
|
||||
LimeSDROutputSettings();
|
||||
void resetToDefaults();
|
||||
|
@ -538,6 +538,19 @@ bool LimeSDRInput::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() << "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<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
|
||||
std::vector<DeviceSourceAPI*>::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<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
|
||||
std::vector<DeviceSinkAPI*>::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<<m_settings.m_log2SoftDecim) << "S/s"
|
||||
@ -1095,7 +1156,9 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc
|
||||
<< " m_lpfFIREnable: " << m_settings.m_lpfFIREnable
|
||||
<< " m_ncoEnable: " << m_settings.m_ncoEnable
|
||||
<< " m_ncoFrequency: " << m_settings.m_ncoFrequency
|
||||
<< " m_antennaPath: " << m_settings.m_antennaPath;
|
||||
<< " m_antennaPath: " << m_settings.m_antennaPath
|
||||
<< " m_extClock: " << m_settings.m_extClock
|
||||
<< " m_extClockFreq: " << m_settings.m_extClockFreq;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ void LimeSDRInputSettings::resetToDefaults()
|
||||
m_lnaGain = 15;
|
||||
m_tiaGain = 2;
|
||||
m_pgaGain = 16;
|
||||
m_extClock = false;
|
||||
m_extClockFreq = 10000000; // 10 MHz
|
||||
}
|
||||
|
||||
QByteArray LimeSDRInputSettings::serialize() const
|
||||
@ -63,6 +65,8 @@ QByteArray LimeSDRInputSettings::serialize() const
|
||||
s.writeU32(15, m_lnaGain);
|
||||
s.writeU32(16, m_tiaGain);
|
||||
s.writeU32(17, m_pgaGain);
|
||||
s.writeBool(18, m_extClock);
|
||||
s.writeU32(19, m_extClockFreq);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
@ -99,6 +103,8 @@ bool LimeSDRInputSettings::deserialize(const QByteArray& data)
|
||||
d.readU32(15, &m_lnaGain, 15);
|
||||
d.readU32(16, &m_tiaGain, 2);
|
||||
d.readU32(17, &m_pgaGain, 16);
|
||||
d.readBool(18, &m_extClock, false);
|
||||
d.readU32(19, &m_extClockFreq, 10000000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ struct LimeSDRInputSettings
|
||||
uint32_t m_lnaGain; //!< Manual LAN gain
|
||||
uint32_t m_tiaGain; //!< Manual TIA gain
|
||||
uint32_t m_pgaGain; //!< Manual PGA gain
|
||||
bool m_extClock; //!< True if external clock source
|
||||
uint32_t m_extClockFreq; //!< Frequency (Hz) of external clock source
|
||||
|
||||
LimeSDRInputSettings();
|
||||
void resetToDefaults();
|
||||
|
Loading…
Reference in New Issue
Block a user