diff --git a/devices/limesdr/devicelimesdrparam.h b/devices/limesdr/devicelimesdrparam.h
index 6138b0b80..4f3c20c67 100644
--- a/devices/limesdr/devicelimesdrparam.h
+++ b/devices/limesdr/devicelimesdrparam.h
@@ -28,8 +28,7 @@
*/
struct DeviceLimeSDRParams
{
- lms_device_t *m_dev; //!< device handle if the party has ownership else 0
- int m_channel; //!< logical device channel number (-1 if none)
+ lms_device_t *m_dev; //!< device handle
int m_nbRxChannels; //!< number of Rx channels (normally 2, we'll see if we really use it...)
int m_nbTxChannels; //!< number of Tx channels (normally 2, we'll see if we really use it...)
lms_range_t m_lpfRangeRx; //!< Low pass filter range information (Rx side)
@@ -46,7 +45,6 @@ struct DeviceLimeSDRParams
DeviceLimeSDRParams() :
m_dev(0),
- m_channel(-1),
m_nbRxChannels(0),
m_nbTxChannels(0),
m_sampleRate(1e6),
@@ -62,6 +60,7 @@ struct DeviceLimeSDRParams
*/
bool open(lms_info_str_t deviceStr);
void close();
+ lms_device_t *getDevice() { return m_dev; }
~DeviceLimeSDRParams()
{
diff --git a/devices/limesdr/devicelimesdrshared.h b/devices/limesdr/devicelimesdrshared.h
new file mode 100644
index 000000000..ae8a79ce9
--- /dev/null
+++ b/devices/limesdr/devicelimesdrshared.h
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////////
+// 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 . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef DEVICES_LIMESDR_DEVICELIMESDRSHARED_H_
+#define DEVICES_LIMESDR_DEVICELIMESDRSHARED_H_
+
+#include
+#include "devicelimesdrparam.h"
+
+/**
+ * Structure shared by a buddy with other buddies
+ */
+struct DeviceLimeSDRShared
+{
+ DeviceLimeSDRParams *m_deviceParams; //!< unique hardware device parameters
+ std::size_t m_channel; //!< logical device channel number (-1 if none)
+
+ DeviceLimeSDRShared() :
+ m_deviceParams(0),
+ m_channel(-1)
+ {}
+
+ ~DeviceLimeSDRShared()
+ {}
+};
+
+#endif /* DEVICES_LIMESDR_DEVICELIMESDRSHARED_H_ */
diff --git a/plugins/samplesource/limesdrinput/limesdrinput.cpp b/plugins/samplesource/limesdrinput/limesdrinput.cpp
index ad267588f..46ef22560 100644
--- a/plugins/samplesource/limesdrinput/limesdrinput.cpp
+++ b/plugins/samplesource/limesdrinput/limesdrinput.cpp
@@ -15,8 +15,12 @@
///////////////////////////////////////////////////////////////////////////////////
#include
+#include
#include
+#include "lime/LimeSuite.h"
+
#include "limesdrinput.h"
+#include "limesdr/devicelimesdrparam.h"
LimeSDRInput::LimeSDRInput(DeviceSourceAPI *deviceAPI) :
@@ -42,33 +46,40 @@ bool LimeSDRInput::openDevice()
if (m_deviceAPI->getSourceBuddies().size() > 0) // look source sibling first
{
DeviceSinkAPI *sourceBuddy = m_deviceAPI->getSourceBuddies()[0];
- m_deviceParams = *(sourceBuddy->getBuddySharedPtr()); // copy parameters
+ m_deviceShared = *(sourceBuddy->getBuddySharedPtr()); // copy shared data
+ DeviceLimeSDRParams *deviceParams = m_deviceShared.m_deviceParams; // get device parameters
- if (m_deviceAPI->getSourceBuddies().size() == m_deviceParams.m_nbRxChannels)
+ if (deviceParams == 0)
+ {
+ qCritical("LimeSDRInput::openDevice: cannot get device parameters from Rx buddy");
+ return false; // the device params should have been created by the buddy
+ }
+
+ if (m_deviceAPI->getSourceBuddies().size() == deviceParams->m_nbRxChannels)
{
return false; // no more Rx channels available in device
}
// look for unused channel number
- char *busyChannels = new char[m_deviceParams.m_nbRxChannels];
- memset(busyChannels, 0, m_deviceParams.m_nbRxChannels);
+ char *busyChannels = new char[deviceParams->m_nbRxChannels];
+ memset(busyChannels, 0, deviceParams->m_nbRxChannels);
for (int i = 0; i < m_deviceAPI->getSourceBuddies().size(); i++)
{
DeviceSinkAPI *buddy = m_deviceAPI->getSourceBuddies()[i];
- DeviceLimeSDRParams *buddyParms = buddy->getBuddySharedPtr();
- busyChannels[buddyParms->m_channel] = 1;
+ DeviceLimeSDRShared *buddyShared = buddy->getBuddySharedPtr();
+ busyChannels[buddyShared->m_channel] = 1;
}
- int ch = 0;
+ std::size_t ch = 0;
- for (;ch < m_deviceParams.m_nbRxChannels; ch++)
+ for (;ch < deviceParams->m_nbRxChannels; ch++)
{
if (busyChannels[ch] == 0) {
break; // first available is the good one
}
}
- m_deviceParams.m_channel = ch;
+ m_deviceShared.m_channel = ch;
delete[] busyChannels;
}
// look for Tx buddies and get reference to common parameters
@@ -76,63 +87,101 @@ bool LimeSDRInput::openDevice()
else if (m_deviceAPI->getSinkBuddies().size() > 0) // then sink
{
DeviceSinkAPI *sinkBuddy = m_deviceAPI->getSinkBuddies()[0];
- m_deviceParams = *(sinkBuddy->getBuddySharedPtr()); // copy parameters
- m_deviceParams.m_channel = 0; // take first channel
+ m_deviceShared = *(sinkBuddy->getBuddySharedPtr()); // copy parameters
+
+ if (m_deviceShared.m_deviceParams == 0)
+ {
+ qCritical("LimeSDRInput::openDevice: cannot get device parameters from Tx buddy");
+ return false; // the device params should have been created by the buddy
+ }
+
+ m_deviceShared.m_channel = 0; // take first channel
}
// There are no buddies then create the first LimeSDR common parameters
// open the device this will also populate common fields
// take the first Rx channel
else
{
- m_deviceParams.open((lms_info_str_t) qPrintable(m_deviceAPI->getSampleSourceSerial()));
- m_deviceParams.m_channel = 0; // take first channel
+ m_deviceShared.m_deviceParams = new DeviceLimeSDRParams();
+ m_deviceShared.m_deviceParams->open((lms_info_str_t) qPrintable(m_deviceAPI->getSampleSourceSerial()));
+ m_deviceShared.m_channel = 0; // take first channel
}
- m_deviceAPI->setBuddySharedPtr(&m_deviceParams); // propagate common parameters to API
+ m_deviceAPI->setBuddySharedPtr(&m_deviceShared); // propagate common parameters to API
- // TODO: acquire the channel
+ // acquire the channel
+
+ if (LMS_EnableChannel(m_deviceShared.m_deviceParams->getDevice(), LMS_CH_RX, m_deviceShared.m_channel, true) != 0)
+ {
+ qCritical("LimeSDRInput::openDevice: cannot enable Rx channel %u", m_deviceShared.m_channel);
+ return false;
+ }
+
+ // set up the stream
+
+ m_streamId.channel = m_deviceShared.m_channel; //channel number
+ m_streamId.channel.fifoSize = 1024 * 1024; //fifo size in samples TODO: adjust if necessary
+ m_streamId.throughputVsLatency = 1.0; //optimize for max throughput
+ m_streamId.isTx = false; //RX 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("LimeSDRInput::openDevice: cannot setup the stream on Rx channel %u", m_deviceShared.m_channel);
+ return false;
+ }
+
+ // TODO: start / stop streaming is done in the thread. You will need to pass the stream Id to the thread at thread creation
return true;
}
void LimeSDRInput::closeDevice()
{
- // TODO: release the channel
+ // destroy the stream
- // No buddies effectively close the device
- if ((m_deviceAPI->getSinkBuddies().size() == 0) && (m_deviceAPI->getSourceBuddies().size() == 0))
+ LMS_DestroyStream(m_deviceShared.m_deviceParams->getDevice(), &m_streamId);
+
+ // release the channel
+
+ if (LMS_EnableChannel(m_deviceShared.m_deviceParams->getDevice(), LMS_CH_RX, m_deviceShared.m_channel, false) != 0)
{
- m_deviceParams.close();
+ qWarning("LimeSDRInput::closeDevice: cannot disable Rx channel %u", m_deviceShared.m_channel);
}
- m_deviceParams.m_dev = 0;
+ m_deviceShared.m_channel = -1;
+
+ // No buddies so effectively close the device
+
+ if ((m_deviceAPI->getSinkBuddies().size() == 0) && (m_deviceAPI->getSourceBuddies().size() == 0))
+ {
+ m_deviceShared.m_deviceParams->close();
+ delete m_deviceShared.m_deviceParams;
+ m_deviceShared.m_deviceParams = 0;
+ }
}
bool LimeSDRInput::start()
{
- QMutexLocker mutexLocker(&m_mutex);
-
- if (!m_deviceParams.m_dev) {
+ if (!m_deviceShared.m_dev) {
return false;
}
if (m_running) stop();
- if ((m_limeSDRInputThread = new LimeSDRInputThread(m_deviceParams.m_dev, &m_sampleFifo)) == 0)
+ if ((m_limeSDRInputThread = new LimeSDRInputThread(m_deviceShared.m_deviceParams->getDevice(), &m_sampleFifo)) == 0)
{
qFatal("LimeSDRInput::start: out of memory");
stop();
return false;
}
- m_limeSDRInputThread->setSamplerate(m_settings.m_devSampleRate);
- m_limeSDRInputThread->setLog2Decimation(m_settings.m_log2Decim);
+ m_limeSDRInputThread->setSamplerate(m_deviceShared.m_deviceParams->m_sampleRate);
+ m_limeSDRInputThread->setLog2Decimation(m_settings.m_log2SoftDecim);
m_limeSDRInputThread->setFcPos((int) m_settings.m_fcPos);
m_limeSDRInputThread->startWork();
- mutexLocker.unlock();
-
applySettings(m_settings, true);
m_running = true;
@@ -141,8 +190,6 @@ bool LimeSDRInput::start()
void LimeSDRInput::stop()
{
- QMutexLocker mutexLocker(&m_mutex);
-
if (m_limeSDRInputThread != 0)
{
m_limeSDRInputThread->stopWork();
diff --git a/plugins/samplesource/limesdrinput/limesdrinput.h b/plugins/samplesource/limesdrinput/limesdrinput.h
index 1c779b84e..43b155437 100644
--- a/plugins/samplesource/limesdrinput/limesdrinput.h
+++ b/plugins/samplesource/limesdrinput/limesdrinput.h
@@ -19,7 +19,7 @@
#include
#include "dsp/devicesamplesource.h"
-#include "limesdr/devicelimesdrparam.h"
+#include "limesdr/devicelimesdrshared.h"
#include "limesdrinputsettings.h"
class DeviceSourceAPI;
@@ -48,7 +48,9 @@ private:
LimeSDRInputThread* m_limeSDRInputThread;
QString m_deviceDescription;
bool m_running;
- DeviceLimeSDRParams m_deviceParams;
+ DeviceLimeSDRShared m_deviceShared;
+
+ lms_stream_t m_streamId;
bool openDevice();
void closeDevice();