kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			LimeSDR: handle clock source change in source and sink
							rodzic
							
								
									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(); | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 f4exb
						f4exb