| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2017 Edouard Griffiths, F4EXB                                   //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify          //
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,               //
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
					
						
							|  |  |  | // GNU General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QMutexLocker>
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | #include <cstddef>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include "lime/LimeSuite.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "device/devicesourceapi.h"
 | 
					
						
							|  |  |  | #include "device/devicesinkapi.h"
 | 
					
						
							|  |  |  | #include "dsp/dspcommands.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-22 09:33:41 +00:00
										 |  |  | #include "limesdroutputthread.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | #include "limesdr/devicelimesdrparam.h"
 | 
					
						
							|  |  |  | #include "limesdr/devicelimesdr.h"
 | 
					
						
							|  |  |  | #include "limesdroutput.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgConfigureLimeSDR, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgGetStreamInfo, Message) | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  | MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgGetDeviceInfo, Message) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | MESSAGE_CLASS_DEFINITION(LimeSDROutput::MsgReportStreamInfo, Message) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LimeSDROutput::LimeSDROutput(DeviceSinkAPI *deviceAPI) : | 
					
						
							|  |  |  |     m_deviceAPI(deviceAPI), | 
					
						
							|  |  |  |     m_settings(), | 
					
						
							|  |  |  |     m_limeSDROutputThread(0), | 
					
						
							| 
									
										
										
										
											2017-09-18 21:29:55 +00:00
										 |  |  |     m_deviceDescription("LimeSDROutput"), | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     m_running(false), | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |     m_channelAcquired(false) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-15 15:37:53 +00:00
										 |  |  |     m_sampleSourceFifo.resize(16*LIMESDROUTPUT_BLOCKSIZE); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     m_streamId.handle = 0; | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     suspendRxBuddies(); | 
					
						
							|  |  |  |     suspendTxBuddies(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     openDevice(); | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     resumeTxBuddies(); | 
					
						
							|  |  |  |     resumeRxBuddies(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LimeSDROutput::~LimeSDROutput() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_running) stop(); | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     suspendRxBuddies(); | 
					
						
							|  |  |  |     suspendTxBuddies(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     closeDevice(); | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     resumeTxBuddies(); | 
					
						
							|  |  |  |     resumeRxBuddies(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-16 09:34:25 +00:00
										 |  |  | void LimeSDROutput::destroy() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete this; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | bool LimeSDROutput::openDevice() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-02 09:30:07 +00:00
										 |  |  |     int requestedChannel = m_deviceAPI->getItemIndex(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     // look for Tx buddies and get reference to common parameters
 | 
					
						
							|  |  |  |     // if there is a channel left take the first available
 | 
					
						
							|  |  |  |     if (m_deviceAPI->getSinkBuddies().size() > 0) // look sink sibling first
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::openDevice: look in Ix buddies"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         DeviceSinkAPI *sinkBuddy = m_deviceAPI->getSinkBuddies()[0]; | 
					
						
							|  |  |  |         m_deviceShared = *((DeviceLimeSDRShared *) sinkBuddy->getBuddySharedPtr()); // copy shared data
 | 
					
						
							|  |  |  |         DeviceLimeSDRParams *deviceParams = m_deviceShared.m_deviceParams; // get device parameters
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (deviceParams == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qCritical("LimeSDROutput::openDevice: cannot get device parameters from Tx buddy"); | 
					
						
							|  |  |  |             return false; // the device params should have been created by the buddy
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug("LimeSDROutput::openDevice: getting device parameters from Tx buddy"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_deviceAPI->getSinkBuddies().size() == deviceParams->m_nbTxChannels) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qCritical("LimeSDROutput::openDevice: no more Tx channels available in device"); | 
					
						
							|  |  |  |             return false; // no more Tx channels available in device
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug("LimeSDROutput::openDevice: at least one more Tx channel is available in device"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 09:30:07 +00:00
										 |  |  |         // check if the requested channel is busy and abort if so (should not happen if device management is working correctly)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         char *busyChannels = new char[deviceParams->m_nbTxChannels]; | 
					
						
							|  |  |  |         memset(busyChannels, 0, deviceParams->m_nbTxChannels); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-25 18:13:34 +00:00
										 |  |  |         for (unsigned int i = 0; i < m_deviceAPI->getSinkBuddies().size(); i++) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             DeviceSinkAPI *buddy = m_deviceAPI->getSinkBuddies()[i]; | 
					
						
							|  |  |  |             DeviceLimeSDRShared *buddyShared = (DeviceLimeSDRShared *) buddy->getBuddySharedPtr(); | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 09:30:07 +00:00
										 |  |  |             if (buddyShared->m_channel == requestedChannel) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 qCritical("LimeSDROutput::openDevice: cannot open busy channel %u", requestedChannel); | 
					
						
							|  |  |  |                 return false; | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 09:30:07 +00:00
										 |  |  |         m_deviceShared.m_channel = requestedChannel; // acknowledge the requested channel
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         delete[] busyChannels; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // look for Rx buddies and get reference to common parameters
 | 
					
						
							|  |  |  |     // take the first Rx channel
 | 
					
						
							|  |  |  |     else if (m_deviceAPI->getSourceBuddies().size() > 0) // then source
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::openDevice: look in Rx buddies"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         DeviceSourceAPI *sourceBuddy = m_deviceAPI->getSourceBuddies()[0]; | 
					
						
							|  |  |  |         m_deviceShared = *((DeviceLimeSDRShared *) sourceBuddy->getBuddySharedPtr()); // copy parameters
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_deviceShared.m_deviceParams == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qCritical("LimeSDROutput::openDevice: cannot get device parameters from Rx buddy"); | 
					
						
							|  |  |  |             return false; // the device params should have been created by the buddy
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug("LimeSDROutput::openDevice: getting device parameters from Rx buddy"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 09:30:07 +00:00
										 |  |  |         m_deviceShared.m_channel = requestedChannel; // acknowledge the requested channel
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     // There are no buddies then create the first LimeSDR common parameters
 | 
					
						
							|  |  |  |     // open the device this will also populate common fields
 | 
					
						
							|  |  |  |     // take the first Tx channel
 | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::openDevice: open device here"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_deviceShared.m_deviceParams = new DeviceLimeSDRParams(); | 
					
						
							|  |  |  |         char serial[256]; | 
					
						
							|  |  |  |         strcpy(serial, qPrintable(m_deviceAPI->getSampleSinkSerial())); | 
					
						
							|  |  |  |         m_deviceShared.m_deviceParams->open(serial); | 
					
						
							| 
									
										
										
										
											2017-11-02 09:30:07 +00:00
										 |  |  |         m_deviceShared.m_channel = requestedChannel; // acknowledge the requested channel
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_deviceAPI->setBuddySharedPtr(&m_deviceShared); // propagate common parameters to API
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 02:01:00 +00:00
										 |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  | void LimeSDROutput::suspendRxBuddies() | 
					
						
							| 
									
										
										
										
											2017-04-23 02:01:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies(); | 
					
						
							|  |  |  |     std::vector<DeviceSourceAPI*>::const_iterator itSource = sourceBuddies.begin(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     qDebug("LimeSDROutput::suspendRxBuddies (%lu)", sourceBuddies.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     for (; itSource != sourceBuddies.end(); ++itSource) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |         DeviceLimeSDRShared *buddySharedPtr = (DeviceLimeSDRShared *) (*itSource)->getBuddySharedPtr(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |         if (buddySharedPtr->m_thread && buddySharedPtr->m_thread->isRunning()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             buddySharedPtr->m_thread->stopWork(); | 
					
						
							|  |  |  |             buddySharedPtr->m_threadWasRunning = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             buddySharedPtr->m_threadWasRunning = false; | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  | void LimeSDROutput::suspendTxBuddies() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies(); | 
					
						
							|  |  |  |     std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin(); | 
					
						
							| 
									
										
										
										
											2017-04-23 01:44:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     qDebug("LimeSDROutput::suspendTxBuddies (%lu)", sinkBuddies.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     for (; itSink != sinkBuddies.end(); ++itSink) | 
					
						
							| 
									
										
										
										
											2017-04-23 01:44:19 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |         DeviceLimeSDRShared *buddySharedPtr = (DeviceLimeSDRShared *) (*itSink)->getBuddySharedPtr(); | 
					
						
							| 
									
										
										
										
											2017-04-23 01:44:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |         if (buddySharedPtr->m_thread && buddySharedPtr->m_thread->isRunning()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             buddySharedPtr->m_thread->stopWork(); | 
					
						
							|  |  |  |             buddySharedPtr->m_threadWasRunning = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             buddySharedPtr->m_threadWasRunning = false; | 
					
						
							| 
									
										
										
										
											2017-04-23 01:44:19 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  | void LimeSDROutput::resumeRxBuddies() | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies(); | 
					
						
							|  |  |  |     std::vector<DeviceSourceAPI*>::const_iterator itSource = sourceBuddies.begin(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     qDebug("LimeSDROutput::resumeRxBuddies (%lu)", sourceBuddies.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     for (; itSource != sourceBuddies.end(); ++itSource) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |         DeviceLimeSDRShared *buddySharedPtr = (DeviceLimeSDRShared *) (*itSource)->getBuddySharedPtr(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |         if (buddySharedPtr->m_threadWasRunning) { | 
					
						
							|  |  |  |             buddySharedPtr->m_thread->startWork(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  | void LimeSDROutput::resumeTxBuddies() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies(); | 
					
						
							|  |  |  |     std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin(); | 
					
						
							| 
									
										
										
										
											2017-04-23 02:01:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     qDebug("LimeSDROutput::resumeTxBuddies (%lu)", sinkBuddies.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     for (; itSink != sinkBuddies.end(); ++itSink) | 
					
						
							| 
									
										
										
										
											2017-04-23 02:01:00 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |         DeviceLimeSDRShared *buddySharedPtr = (DeviceLimeSDRShared *) (*itSink)->getBuddySharedPtr(); | 
					
						
							| 
									
										
										
										
											2017-04-23 02:01:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |         if (buddySharedPtr->m_threadWasRunning) { | 
					
						
							|  |  |  |             buddySharedPtr->m_thread->startWork(); | 
					
						
							| 
									
										
										
										
											2017-04-23 02:01:00 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LimeSDROutput::closeDevice() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_deviceShared.m_deviceParams->getDevice() == 0) { // was never open
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |     if (m_running) stop(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // No buddies so effectively close the device
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_deviceAPI->getSourceBuddies().size() == 0) && (m_deviceAPI->getSinkBuddies().size() == 0)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_deviceShared.m_deviceParams->close(); | 
					
						
							|  |  |  |         delete m_deviceShared.m_deviceParams; | 
					
						
							|  |  |  |         m_deviceShared.m_deviceParams = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_deviceShared.m_channel = -1; // effectively release the channel for the possible buddies
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool LimeSDROutput::acquireChannel() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-30 18:25:20 +00:00
										 |  |  |     suspendRxBuddies(); | 
					
						
							|  |  |  |     suspendTxBuddies(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |     // acquire the channel
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (LMS_EnableChannel(m_deviceShared.m_deviceParams->getDevice(), LMS_CH_TX, m_deviceShared.m_channel, true) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qCritical("LimeSDROutput::acquireChannel: cannot enable Tx channel %d", m_deviceShared.m_channel); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::acquireChannel: Tx channel %d enabled", m_deviceShared.m_channel); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // set up the stream
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_streamId.channel =  m_deviceShared.m_channel; // channel number
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     m_streamId.fifoSize = 1024 * 1024;              // fifo size in samples (SR / 10 take ~5MS/s)
 | 
					
						
							|  |  |  |     m_streamId.throughputVsLatency = 0.5;           // optimize for min latency
 | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |     m_streamId.isTx = true;                         // TX channel
 | 
					
						
							|  |  |  |     m_streamId.dataFmt = lms_stream_t::LMS_FMT_I12; // 12-bit integers
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (LMS_SetupStream(m_deviceShared.m_deviceParams->getDevice(), &m_streamId) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qCritical("LimeSDROutput::acquireChannel: cannot setup the stream on Tx channel %d", m_deviceShared.m_channel); | 
					
						
							| 
									
										
										
										
											2017-09-30 18:25:20 +00:00
										 |  |  |         resumeTxBuddies(); | 
					
						
							|  |  |  |         resumeRxBuddies(); | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::acquireChannel: stream set up on Tx channel %d", m_deviceShared.m_channel); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:25:20 +00:00
										 |  |  |     resumeTxBuddies(); | 
					
						
							|  |  |  |     resumeRxBuddies(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     m_channelAcquired = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LimeSDROutput::releaseChannel() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-30 18:25:20 +00:00
										 |  |  |     suspendRxBuddies(); | 
					
						
							|  |  |  |     suspendTxBuddies(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     // destroy the stream
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (LMS_DestroyStream(m_deviceShared.m_deviceParams->getDevice(), &m_streamId) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qWarning("LimeSDROutput::releaseChannel: cannot destroy the stream on Tx channel %d", m_deviceShared.m_channel); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::releaseChannel: stream destroyed on Tx channel %d", m_deviceShared.m_channel); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     m_streamId.handle = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // release the channel
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (LMS_EnableChannel(m_deviceShared.m_deviceParams->getDevice(), LMS_CH_TX, m_deviceShared.m_channel, false) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |         qWarning("LimeSDROutput::releaseChannel: cannot disable Tx channel %d", m_deviceShared.m_channel); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::releaseChannel: Tx channel %d released", m_deviceShared.m_channel); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:25:20 +00:00
										 |  |  |     resumeTxBuddies(); | 
					
						
							|  |  |  |     resumeRxBuddies(); | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_channelAcquired = false; | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool LimeSDROutput::start() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_deviceShared.m_deviceParams->getDevice()) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-30 18:07:08 +00:00
										 |  |  |     if (m_running) { stop(); } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     if (!acquireChannel()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 22:23:12 +00:00
										 |  |  |     applySettings(m_settings, true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     // start / stop streaming is done in the thread.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_limeSDROutputThread = new LimeSDROutputThread(&m_streamId, &m_sampleSourceFifo)) == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qFatal("LimeSDROutput::start: cannot create thread"); | 
					
						
							|  |  |  |         stop(); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::start: thread created"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_limeSDROutputThread->setLog2Interpolation(m_settings.m_log2SoftInterp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_limeSDROutputThread->startWork(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 08:45:33 +00:00
										 |  |  |     m_deviceShared.m_thread = m_limeSDROutputThread; | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     m_running = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LimeSDROutput::stop() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     qDebug("LimeSDROutput::stop"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     if (m_limeSDROutputThread != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_limeSDROutputThread->stopWork(); | 
					
						
							|  |  |  |         delete m_limeSDROutputThread; | 
					
						
							|  |  |  |         m_limeSDROutputThread = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_deviceShared.m_thread = 0; | 
					
						
							|  |  |  |     m_running = false; | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-25 22:48:50 +00:00
										 |  |  |     releaseChannel(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const QString& LimeSDROutput::getDeviceDescription() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_deviceDescription; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int LimeSDROutput::getSampleRate() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int rate = m_settings.m_devSampleRate; | 
					
						
							|  |  |  |     return (rate / (1<<m_settings.m_log2SoftInterp)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | quint64 LimeSDROutput::getCenterFrequency() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_settings.m_centerFrequency; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::size_t LimeSDROutput::getChannelIndex() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_deviceShared.m_channel; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LimeSDROutput::getLORange(float& minF, float& maxF, float& stepF) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     lms_range_t range = m_deviceShared.m_deviceParams->m_loRangeTx; | 
					
						
							|  |  |  |     minF = range.min; | 
					
						
							|  |  |  |     maxF = range.max; | 
					
						
							|  |  |  |     stepF = range.step; | 
					
						
							|  |  |  |     qDebug("LimeSDROutput::getLORange: min: %f max: %f step: %f", range.min, range.max, range.step); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LimeSDROutput::getSRRange(float& minF, float& maxF, float& stepF) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     lms_range_t range = m_deviceShared.m_deviceParams->m_srRangeTx; | 
					
						
							|  |  |  |     minF = range.min; | 
					
						
							|  |  |  |     maxF = range.max; | 
					
						
							|  |  |  |     stepF = range.step; | 
					
						
							|  |  |  |     qDebug("LimeSDROutput::getSRRange: min: %f max: %f step: %f", range.min, range.max, range.step); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LimeSDROutput::getLPRange(float& minF, float& maxF, float& stepF) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     lms_range_t range = m_deviceShared.m_deviceParams->m_lpfRangeTx; | 
					
						
							|  |  |  |     minF = range.min; | 
					
						
							|  |  |  |     maxF = range.max; | 
					
						
							|  |  |  |     stepF = range.step; | 
					
						
							|  |  |  |     qDebug("LimeSDROutput::getLPRange: min: %f max: %f step: %f", range.min, range.max, range.step); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint32_t LimeSDROutput::getHWLog2Interp() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_deviceShared.m_deviceParams->m_log2OvSRTx; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool LimeSDROutput::handleMessage(const Message& message) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (MsgConfigureLimeSDR::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         MsgConfigureLimeSDR& conf = (MsgConfigureLimeSDR&) message; | 
					
						
							|  |  |  |         qDebug() << "LimeSDROutput::handleMessage: MsgConfigureLimeSDR"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-14 04:30:31 +00:00
										 |  |  |         if (!applySettings(conf.getSettings(), conf.getForce())) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             qDebug("LimeSDROutput::handleMessage config error"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-24 23:38:39 +00:00
										 |  |  |     else if (DeviceLimeSDRShared::MsgReportBuddyChange::match(message)) | 
					
						
							| 
									
										
										
										
											2017-10-24 00:20:57 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-10-24 23:38:39 +00:00
										 |  |  |         DeviceLimeSDRShared::MsgReportBuddyChange& report = (DeviceLimeSDRShared::MsgReportBuddyChange&) message; | 
					
						
							| 
									
										
										
										
											2017-10-24 00:20:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (report.getRxElseTx()) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-10-25 23:47:43 +00:00
										 |  |  |             double host_Hz; | 
					
						
							|  |  |  |             double rf_Hz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (LMS_GetSampleRate(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                     LMS_CH_TX, | 
					
						
							|  |  |  |                     m_deviceShared.m_channel, | 
					
						
							|  |  |  |                     &host_Hz, | 
					
						
							|  |  |  |                     &rf_Hz) < 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 qDebug("LimeSDROutput::handleMessage: MsgReportBuddyChange: LMS_GetSampleRate() failed"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 m_settings.m_devSampleRate = roundf(host_Hz); | 
					
						
							|  |  |  |                 int hard = roundf(rf_Hz) / m_settings.m_devSampleRate; | 
					
						
							|  |  |  |                 m_settings.m_log2HardInterp = log2(hard); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 qDebug() << "LimeSDROutput::handleMessage: MsgReportBuddyChange:" | 
					
						
							|  |  |  |                          << " host_Hz: " << host_Hz | 
					
						
							|  |  |  |                          << " rf_Hz: " << rf_Hz | 
					
						
							|  |  |  |                          << " m_devSampleRate: " << m_settings.m_devSampleRate | 
					
						
							|  |  |  |                          << " log2Hard: " << hard | 
					
						
							|  |  |  |                          << " m_log2HardInterp: " << m_settings.m_log2HardInterp; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 00:20:57 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-10-24 23:38:39 +00:00
										 |  |  |             m_settings.m_devSampleRate   = report.getDevSampleRate(); | 
					
						
							|  |  |  |             m_settings.m_log2HardInterp  = report.getLog2HardDecimInterp(); | 
					
						
							|  |  |  |             m_settings.m_centerFrequency = report.getCenterFrequency(); | 
					
						
							| 
									
										
										
										
											2017-10-24 00:20:57 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_settings.m_ncoEnable) // need to reset NCO after sample rate change
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             applySettings(m_settings, false, true); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int ncoShift = m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         DSPSignalNotification *notif = new DSPSignalNotification( | 
					
						
							|  |  |  |                 m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftInterp), | 
					
						
							|  |  |  |                 m_settings.m_centerFrequency + ncoShift); | 
					
						
							|  |  |  |         m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 23:38:39 +00:00
										 |  |  |         DeviceLimeSDRShared::MsgReportBuddyChange *reportToGUI = DeviceLimeSDRShared::MsgReportBuddyChange::create( | 
					
						
							|  |  |  |                 m_settings.m_devSampleRate, m_settings.m_log2HardInterp, m_settings.m_centerFrequency, false); | 
					
						
							| 
									
										
										
										
											2017-10-24 00:20:57 +00:00
										 |  |  |         getMessageQueueToGUI()->push(reportToGUI); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-11-04 01:18:16 +00:00
										 |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     else if (MsgGetStreamInfo::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | //        qDebug() << "LimeSDROutput::handleMessage: MsgGetStreamInfo";
 | 
					
						
							|  |  |  |         lms_stream_status_t status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_streamId.handle && (LMS_GetStreamStatus(&m_streamId, &status) == 0)) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-09-17 15:35:03 +00:00
										 |  |  |             if (m_deviceAPI->getSampleSinkGUIMessageQueue()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 MsgReportStreamInfo *report = MsgReportStreamInfo::create( | 
					
						
							|  |  |  |                         true, // Success
 | 
					
						
							|  |  |  |                         status.active, | 
					
						
							|  |  |  |                         status.fifoFilledCount, | 
					
						
							|  |  |  |                         status.fifoSize, | 
					
						
							|  |  |  |                         status.underrun, | 
					
						
							|  |  |  |                         status.overrun, | 
					
						
							|  |  |  |                         status.droppedPackets, | 
					
						
							|  |  |  |                         status.sampleRate, | 
					
						
							|  |  |  |                         status.linkRate, | 
					
						
							|  |  |  |                         status.timestamp); | 
					
						
							|  |  |  |                 m_deviceAPI->getSampleSinkGUIMessageQueue()->push(report); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-09-17 15:35:03 +00:00
										 |  |  |             if (m_deviceAPI->getSampleSinkGUIMessageQueue()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 MsgReportStreamInfo *report = MsgReportStreamInfo::create( | 
					
						
							|  |  |  |                         false, // Success
 | 
					
						
							|  |  |  |                         false, // status.active,
 | 
					
						
							|  |  |  |                         0,     // status.fifoFilledCount,
 | 
					
						
							|  |  |  |                         16384, // status.fifoSize,
 | 
					
						
							|  |  |  |                         0,     // status.underrun,
 | 
					
						
							|  |  |  |                         0,     // status.overrun,
 | 
					
						
							|  |  |  |                         0,     // status.droppedPackets,
 | 
					
						
							|  |  |  |                         0,     // status.sampleRate,
 | 
					
						
							|  |  |  |                         0,     // status.linkRate,
 | 
					
						
							|  |  |  |                         0);    // status.timestamp);
 | 
					
						
							|  |  |  |                 m_deviceAPI->getSampleSinkGUIMessageQueue()->push(report); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  |     else if (MsgGetDeviceInfo::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-07-03 21:29:06 +00:00
										 |  |  |         double temp = 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_deviceShared.m_deviceParams->getDevice() && (LMS_GetChipTemperature(m_deviceShared.m_deviceParams->getDevice(), 0, &temp) == 0)) | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-07-03 21:29:06 +00:00
										 |  |  |             //qDebug("LimeSDROutput::handleMessage: MsgGetDeviceInfo: temperature: %f", temp);
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug("LimeSDROutput::handleMessage: MsgGetDeviceInfo: cannot get temperature"); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 21:29:06 +00:00
										 |  |  |         // send to oneself
 | 
					
						
							| 
									
										
										
										
											2017-09-17 15:35:03 +00:00
										 |  |  |         if (getMessageQueueToGUI()) { | 
					
						
							|  |  |  |             DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); | 
					
						
							|  |  |  |             getMessageQueueToGUI()->push(report); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 21:29:06 +00:00
										 |  |  |         // send to source buddies
 | 
					
						
							|  |  |  |         const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies(); | 
					
						
							|  |  |  |         std::vector<DeviceSourceAPI*>::const_iterator itSource = sourceBuddies.begin(); | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 21:29:06 +00:00
										 |  |  |         for (; itSource != sourceBuddies.end(); ++itSource) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-09-17 15:35:03 +00:00
										 |  |  |             if ((*itSource)->getSampleSourceGUIMessageQueue()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); | 
					
						
							|  |  |  |                 (*itSource)->getSampleSourceGUIMessageQueue()->push(report); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-07-03 21:29:06 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 21:29:06 +00:00
										 |  |  |         // send to sink buddies
 | 
					
						
							|  |  |  |         const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies(); | 
					
						
							|  |  |  |         std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin(); | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 21:29:06 +00:00
										 |  |  |         for (; itSink != sinkBuddies.end(); ++itSink) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-09-17 15:35:03 +00:00
										 |  |  |             if ((*itSink)->getSampleSinkGUIMessageQueue()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); | 
					
						
							|  |  |  |                 (*itSink)->getSampleSinkGUIMessageQueue()->push(report); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-07-03 20:35:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2017-07-03 14:58:46 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 00:20:57 +00:00
										 |  |  | bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool force, bool forceNCOFrequency) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     bool forwardChangeOwnDSP = false; | 
					
						
							|  |  |  |     bool forwardChangeTxDSP  = false; | 
					
						
							|  |  |  |     bool forwardChangeAllDSP = false; | 
					
						
							| 
									
										
										
										
											2017-11-04 01:18:16 +00:00
										 |  |  |     bool forwardClockSource  = false; | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |     bool ownThreadWasRunning = false; | 
					
						
							| 
									
										
										
										
											2017-08-04 08:31:54 +00:00
										 |  |  |     bool doCalibration       = false; | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  |     double clockGenFreq      = 0.0; | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | //  QMutexLocker mutexLocker(&m_mutex);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  |     if (LMS_GetClockFreq(m_deviceShared.m_deviceParams->getDevice(), LMS_CLOCK_CGEN, &clockGenFreq) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qCritical("LimeSDROutput::applySettings: could not get clock gen frequency"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug() << "LimeSDROutput::applySettings: clock gen frequency: " << clockGenFreq; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     // apply settings
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_settings.m_gain != settings.m_gain) || force) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |         if (m_deviceShared.m_deviceParams->getDevice() != 0 && m_channelAcquired) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (LMS_SetGaindB(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                     LMS_CH_TX, | 
					
						
							|  |  |  |                     m_deviceShared.m_channel, | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                     settings.m_gain) < 0) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 qDebug("LimeSDROutput::applySettings: LMS_SetGaindB() failed"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  |                 doCalibration = true; | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                 qDebug() << "LimeSDROutput::applySettings: Gain set to " << settings.m_gain; | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_settings.m_devSampleRate != settings.m_devSampleRate) | 
					
						
							|  |  |  |        || (m_settings.m_log2HardInterp != settings.m_log2HardInterp) || force) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-10-24 00:20:57 +00:00
										 |  |  |         forwardChangeAllDSP = true; //m_settings.m_devSampleRate != settings.m_devSampleRate;
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (m_deviceShared.m_deviceParams->getDevice() != 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (LMS_SetSampleRateDir(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                     LMS_CH_TX, | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                     settings.m_devSampleRate, | 
					
						
							|  |  |  |                     1<<settings.m_log2HardInterp) < 0) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 qCritical("LimeSDROutput::applySettings: could not set sample rate to %d with oversampling of %d", | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                         settings.m_devSampleRate, | 
					
						
							|  |  |  |                         1<<settings.m_log2HardInterp); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                 m_deviceShared.m_deviceParams->m_log2OvSRTx = settings.m_log2HardInterp; | 
					
						
							|  |  |  |                 m_deviceShared.m_deviceParams->m_sampleRate = settings.m_devSampleRate; | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  |                 //doCalibration = true;
 | 
					
						
							| 
									
										
										
										
											2017-08-04 08:31:54 +00:00
										 |  |  |                 forceNCOFrequency = true; | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |                 qDebug("LimeSDROutput::applySettings: set sample rate set to %d with oversampling of %d", | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                         settings.m_devSampleRate, | 
					
						
							|  |  |  |                         1<<settings.m_log2HardInterp); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-07 22:25:13 +00:00
										 |  |  |     if ((m_settings.m_devSampleRate != settings.m_devSampleRate) | 
					
						
							|  |  |  |        || (m_settings.m_log2SoftInterp != settings.m_log2SoftInterp) || force) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int fifoSize = std::max( | 
					
						
							|  |  |  |                 (int) ((settings.m_devSampleRate/(1<<settings.m_log2SoftInterp)) * DeviceLimeSDRShared::m_sampleFifoLengthInSeconds), | 
					
						
							|  |  |  |                 DeviceLimeSDRShared::m_sampleFifoMinSize); | 
					
						
							| 
									
										
										
										
											2017-10-14 04:30:31 +00:00
										 |  |  |         qDebug("LimeSDROutput::applySettings: resize FIFO: %d", fifoSize); | 
					
						
							| 
									
										
										
										
											2017-08-07 22:25:13 +00:00
										 |  |  |         m_sampleSourceFifo.resize(fifoSize); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     if ((m_settings.m_lpfBW != settings.m_lpfBW) || force) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |         if (m_deviceShared.m_deviceParams->getDevice() != 0 && m_channelAcquired) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (LMS_SetLPFBW(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                     LMS_CH_TX, | 
					
						
							|  |  |  |                     m_deviceShared.m_channel, | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                     settings.m_lpfBW) < 0) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                 qCritical("LimeSDROutput::applySettings: could not set LPF to %f Hz", settings.m_lpfBW); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  |                 //doCalibration = true;
 | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                 qDebug("LimeSDROutput::applySettings: LPF set to %f Hz", settings.m_lpfBW); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_settings.m_lpfFIRBW != settings.m_lpfFIRBW) || | 
					
						
							|  |  |  |         (m_settings.m_lpfFIREnable != settings.m_lpfFIREnable) || force) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |         if (m_deviceShared.m_deviceParams->getDevice() != 0 && m_channelAcquired) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (LMS_SetGFIRLPF(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                     LMS_CH_TX, | 
					
						
							|  |  |  |                     m_deviceShared.m_channel, | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                     settings.m_lpfFIREnable, | 
					
						
							|  |  |  |                     settings.m_lpfFIRBW) < 0) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 qCritical("LimeSDROutput::applySettings: could %s and set LPF FIR to %f Hz", | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                         settings.m_lpfFIREnable ? "enable" : "disable", | 
					
						
							|  |  |  |                         settings.m_lpfFIRBW); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  |                 //doCalibration = true;
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |                 qDebug("LimeSDROutput::applySettings: %sd and set LPF FIR to %f Hz", | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                         settings.m_lpfFIREnable ? "enable" : "disable", | 
					
						
							|  |  |  |                         settings.m_lpfFIRBW); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_settings.m_ncoFrequency != settings.m_ncoFrequency) || | 
					
						
							| 
									
										
										
										
											2017-08-04 08:31:54 +00:00
										 |  |  |         (m_settings.m_ncoEnable != settings.m_ncoEnable) || force || forceNCOFrequency) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |         if (m_deviceShared.m_deviceParams->getDevice() != 0 && m_channelAcquired) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (DeviceLimeSDR::setNCOFrequency(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                     LMS_CH_TX, | 
					
						
							|  |  |  |                     m_deviceShared.m_channel, | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                     settings.m_ncoEnable, | 
					
						
							|  |  |  |                     settings.m_ncoFrequency)) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2017-05-08 09:02:31 +00:00
										 |  |  |                 //doCalibration = true;
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |                 forwardChangeOwnDSP = true; | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                 m_deviceShared.m_ncoFrequency = settings.m_ncoEnable ? settings.m_ncoFrequency : 0; // for buddies
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |                 qDebug("LimeSDROutput::applySettings: %sd and set NCO to %d Hz", | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                         settings.m_ncoEnable ? "enable" : "disable", | 
					
						
							|  |  |  |                         settings.m_ncoFrequency); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 qCritical("LimeSDROutput::applySettings: could not %s and set NCO to %d Hz", | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                         settings.m_ncoEnable ? "enable" : "disable", | 
					
						
							|  |  |  |                         settings.m_ncoFrequency); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_settings.m_log2SoftInterp != settings.m_log2SoftInterp) || force) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         forwardChangeOwnDSP = true; | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |         m_deviceShared.m_log2Soft = settings.m_log2SoftInterp; // for buddies
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (m_limeSDROutputThread != 0) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |             m_limeSDROutputThread->setLog2Interpolation(settings.m_log2SoftInterp); | 
					
						
							|  |  |  |             qDebug() << "LimeSDROutput::applySettings: set soft decimation to " << (1<<settings.m_log2SoftInterp); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-07 01:05:29 +00:00
										 |  |  |     if ((m_settings.m_antennaPath != settings.m_antennaPath) || force) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |         if (m_deviceShared.m_deviceParams->getDevice() != 0 && m_channelAcquired) | 
					
						
							| 
									
										
										
										
											2017-05-07 01:05:29 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (DeviceLimeSDR::setTxAntennaPath(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                     m_deviceShared.m_channel, | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                     settings.m_antennaPath)) | 
					
						
							| 
									
										
										
										
											2017-05-07 01:05:29 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 doCalibration = true; | 
					
						
							|  |  |  |                 qDebug("LimeSDRInput::applySettings: set antenna path to %d", | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                         (int) settings.m_antennaPath); | 
					
						
							| 
									
										
										
										
											2017-05-07 01:05:29 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 qCritical("LimeSDRInput::applySettings: could not set antenna path to %d", | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                         (int) settings.m_antennaPath); | 
					
						
							| 
									
										
										
										
											2017-05-07 01:05:29 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         forwardChangeTxDSP = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |         if (m_deviceShared.m_deviceParams->getDevice() != 0 && m_channelAcquired) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (LMS_SetLOFrequency(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                     LMS_CH_TX, | 
					
						
							|  |  |  |                     m_deviceShared.m_channel, // same for both channels anyway but switches antenna port automatically
 | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                     settings.m_centerFrequency) < 0) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                 qCritical("LimeSDROutput::applySettings: could not set frequency to %lu", settings.m_centerFrequency); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 doCalibration = true; | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |                 m_deviceShared.m_centerFrequency = settings.m_centerFrequency; // for buddies
 | 
					
						
							|  |  |  |                 qDebug("LimeSDROutput::applySettings: frequency set to %lu", settings.m_centerFrequency); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-04 01:18:16 +00:00
										 |  |  |     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); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-07 21:41:17 +00:00
										 |  |  |     m_settings = settings; | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  |     double clockGenFreqAfter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (LMS_GetClockFreq(m_deviceShared.m_deviceParams->getDevice(), LMS_CLOCK_CGEN, &clockGenFreqAfter) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qCritical("LimeSDROutput::applySettings: could not get clock gen frequency"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug() << "LimeSDROutput::applySettings: clock gen frequency after: " << clockGenFreqAfter; | 
					
						
							|  |  |  |         doCalibration = doCalibration || (clockGenFreqAfter != clockGenFreq); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |     if (doCalibration && m_channelAcquired) | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  |         if (m_limeSDROutputThread && m_limeSDROutputThread->isRunning()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_limeSDROutputThread->stopWork(); | 
					
						
							|  |  |  |             ownThreadWasRunning = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         suspendRxBuddies(); | 
					
						
							|  |  |  |         suspendTxBuddies(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         if (LMS_Calibrate(m_deviceShared.m_deviceParams->getDevice(), | 
					
						
							|  |  |  |                 LMS_CH_TX, | 
					
						
							|  |  |  |                 m_deviceShared.m_channel, | 
					
						
							|  |  |  |                 m_settings.m_lpfBW, | 
					
						
							|  |  |  |                 0) < 0) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |             qCritical("LimeSDROutput::applySettings: calibration failed on Tx channel %d", m_deviceShared.m_channel); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-08-14 01:32:51 +00:00
										 |  |  |             qDebug("LimeSDROutput::applySettings: calibration successful on Tx channel %d", m_deviceShared.m_channel); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-10-26 21:57:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resumeTxBuddies(); | 
					
						
							|  |  |  |         resumeRxBuddies(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (ownThreadWasRunning) { | 
					
						
							|  |  |  |             m_limeSDROutputThread->startWork(); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // forward changes to buddies or oneself
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (forwardChangeAllDSP) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::applySettings: forward change to all buddies"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int ncoShift = m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // send to self first
 | 
					
						
							| 
									
										
										
										
											2017-04-23 01:36:10 +00:00
										 |  |  |         DSPSignalNotification *notif = new DSPSignalNotification( | 
					
						
							|  |  |  |                 m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftInterp), | 
					
						
							|  |  |  |                 m_settings.m_centerFrequency + ncoShift); | 
					
						
							| 
									
										
										
										
											2017-09-13 21:42:28 +00:00
										 |  |  |         m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // 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) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-10-24 23:38:39 +00:00
										 |  |  |             DeviceLimeSDRShared::MsgReportBuddyChange *report = DeviceLimeSDRShared::MsgReportBuddyChange::create( | 
					
						
							|  |  |  |                     m_settings.m_devSampleRate, m_settings.m_log2HardInterp, m_settings.m_centerFrequency, false); | 
					
						
							| 
									
										
										
										
											2017-09-17 23:05:08 +00:00
										 |  |  |             (*itSink)->getSampleSinkInputMessageQueue()->push(report); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // 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) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-10-24 23:38:39 +00:00
										 |  |  |             DeviceLimeSDRShared::MsgReportBuddyChange *report = DeviceLimeSDRShared::MsgReportBuddyChange::create( | 
					
						
							|  |  |  |                     m_settings.m_devSampleRate, m_settings.m_log2HardInterp, m_settings.m_centerFrequency, false); | 
					
						
							| 
									
										
										
										
											2017-09-17 23:05:08 +00:00
										 |  |  |             (*itSource)->getSampleSourceInputMessageQueue()->push(report); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (forwardChangeTxDSP) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::applySettings: forward change to Tx buddies"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int sampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftInterp); | 
					
						
							|  |  |  |         int ncoShift = m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // send to self first
 | 
					
						
							|  |  |  |         DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency + ncoShift); | 
					
						
							| 
									
										
										
										
											2017-09-13 21:42:28 +00:00
										 |  |  |         m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // 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) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2017-10-24 23:38:39 +00:00
										 |  |  |             DeviceLimeSDRShared::MsgReportBuddyChange *report = DeviceLimeSDRShared::MsgReportBuddyChange::create( | 
					
						
							|  |  |  |                     m_settings.m_devSampleRate, m_settings.m_log2HardInterp, m_settings.m_centerFrequency, false); | 
					
						
							| 
									
										
										
										
											2017-09-17 23:05:08 +00:00
										 |  |  |             (*itSink)->getSampleSinkInputMessageQueue()->push(report); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (forwardChangeOwnDSP) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("LimeSDROutput::applySettings: forward change to self only"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int sampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftInterp); | 
					
						
							|  |  |  |         int ncoShift = m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0; | 
					
						
							|  |  |  |         DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency + ncoShift); | 
					
						
							| 
									
										
										
										
											2017-09-13 21:42:28 +00:00
										 |  |  |         m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-04 01:18:16 +00:00
										 |  |  |     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); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  |     qDebug() << "LimeSDROutput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz" | 
					
						
							|  |  |  |             << " device stream sample rate: " << m_settings.m_devSampleRate << "S/s" | 
					
						
							| 
									
										
										
										
											2017-08-04 15:19:15 +00:00
										 |  |  |             << " sample rate with soft decimation: " << m_settings.m_devSampleRate/(1<<m_settings.m_log2SoftInterp) << "S/s" | 
					
						
							|  |  |  |             << " m_gain: " << m_settings.m_gain | 
					
						
							|  |  |  |             << " m_lpfBW: " << m_settings.m_lpfBW | 
					
						
							|  |  |  |             << " m_lpfFIRBW: " << m_settings.m_lpfFIRBW | 
					
						
							|  |  |  |             << " m_lpfFIREnable: " << m_settings.m_lpfFIREnable | 
					
						
							|  |  |  |             << " m_ncoEnable: " << m_settings.m_ncoEnable | 
					
						
							|  |  |  |             << " m_ncoFrequency: " << m_settings.m_ncoFrequency | 
					
						
							| 
									
										
										
										
											2017-11-04 01:18:16 +00:00
										 |  |  |             << " m_antennaPath: " << m_settings.m_antennaPath | 
					
						
							|  |  |  |             << " m_extClock: " << m_settings.m_extClock | 
					
						
							|  |  |  |             << " m_extClockFreq: " << m_settings.m_extClockFreq; | 
					
						
							| 
									
										
										
										
											2017-04-22 04:40:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |