mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-01-07 08:48:47 -05:00
LimeSDR MIMO: corrections and actual implementation
This commit is contained in:
parent
e62af95d46
commit
1816ab82bf
@ -4,6 +4,10 @@ if(ENABLE_BLADERF AND LIBBLADERF_FOUND)
|
||||
add_subdirectory(bladerf2mimo)
|
||||
endif()
|
||||
|
||||
if(ENABLE_LIMESUITE AND LIMESUITE_FOUND)
|
||||
add_subdirectory(limesdrmimo)
|
||||
endif()
|
||||
|
||||
if(ENABLE_XTRX AND LIBXTRX_FOUND)
|
||||
add_subdirectory(xtrxmimo)
|
||||
endif()
|
||||
|
||||
@ -58,6 +58,8 @@ LimeSDRMIMO::LimeSDRMIMO(DeviceAPI *deviceAPI) :
|
||||
m_txChannelEnabled[channel] = false;
|
||||
m_rxStreamStarted[channel] = false;
|
||||
m_txStreamStarted[channel] = false;
|
||||
m_rxStreams[channel].handle = 0;
|
||||
m_txStreams[channel].handle = 0;
|
||||
}
|
||||
|
||||
m_open = openDevice();
|
||||
@ -163,8 +165,8 @@ bool LimeSDRMIMO::setupRxStream(unsigned int channel)
|
||||
}
|
||||
|
||||
// set up the stream
|
||||
m_rxStreams[channel].channel = channel; // channel number
|
||||
m_rxStreams[channel].fifoSize = 1024 * 1024; // fifo size in samples (SR / 10 take ~5MS/s)
|
||||
m_rxStreams[channel].channel = channel | LMS_ALIGN_CH_PHASE; // channel number
|
||||
m_rxStreams[channel].fifoSize = 10 * 1024 * 1024; // fifo size in samples (SR / 10 take ~5MS/s)
|
||||
m_rxStreams[channel].throughputVsLatency = 0.5; // optimize for min latency
|
||||
m_rxStreams[channel].isTx = false; // RX channel
|
||||
m_rxStreams[channel].dataFmt = lms_stream_t::LMS_FMT_I12; // 12-bit integers
|
||||
@ -202,7 +204,7 @@ bool LimeSDRMIMO::setupTxStream(unsigned int channel)
|
||||
}
|
||||
|
||||
// set up the stream
|
||||
m_txStreams[channel].channel = channel; // channel number
|
||||
m_txStreams[channel].channel = channel | LMS_ALIGN_CH_PHASE; // channel number
|
||||
m_txStreams[channel].fifoSize = 1024 * 1024; // fifo size in samples (SR / 10 take ~5MS/s)
|
||||
m_txStreams[channel].throughputVsLatency = 0.5; // optimize for min latency
|
||||
m_txStreams[channel].isTx = true; // TX channel
|
||||
@ -546,6 +548,87 @@ bool LimeSDRMIMO::handleMessage(const Message& message)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgGetStreamInfo::match(message))
|
||||
{
|
||||
MsgGetStreamInfo& cmd = (MsgGetStreamInfo&) message;
|
||||
lms_stream_status_t status;
|
||||
lms_stream_t *stream;
|
||||
|
||||
if (cmd.getRxElseTx() && (cmd.getChannel() == 0) && m_rxStreams[0].handle) {
|
||||
stream = &m_rxStreams[0];
|
||||
} else if (cmd.getRxElseTx() && (cmd.getChannel() == 1) && m_rxStreams[1].handle) {
|
||||
stream = &m_rxStreams[1];
|
||||
} else if (!cmd.getRxElseTx() && (cmd.getChannel() == 0) && m_txStreams[0].handle) {
|
||||
stream = &m_txStreams[0];
|
||||
} else if (!cmd.getRxElseTx() && (cmd.getChannel() == 1) && m_txStreams[1].handle) {
|
||||
stream = &m_txStreams[1];
|
||||
} else {
|
||||
stream = nullptr;
|
||||
}
|
||||
|
||||
if (stream && (LMS_GetStreamStatus(stream, &status) == 0))
|
||||
{
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportStreamInfo *report = MsgReportStreamInfo::create(
|
||||
true, // Success
|
||||
status.active,
|
||||
status.fifoFilledCount,
|
||||
status.fifoSize,
|
||||
status.underrun,
|
||||
status.overrun,
|
||||
status.droppedPackets,
|
||||
status.linkRate,
|
||||
status.timestamp);
|
||||
getMessageQueueToGUI()->push(report);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_deviceAPI->getSamplingDeviceGUIMessageQueue())
|
||||
{
|
||||
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.linkRate,
|
||||
0); // status.timestamp);
|
||||
m_deviceAPI->getSamplingDeviceGUIMessageQueue()->push(report);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgGetDeviceInfo::match(message))
|
||||
{
|
||||
double temp = 0.0;
|
||||
uint8_t gpioPins = 0;
|
||||
|
||||
if (m_deviceParams->getDevice() && (LMS_GetChipTemperature(m_deviceParams->getDevice(), 0, &temp) != 0)) {
|
||||
qDebug("LimeSDRMIMO::handleMessage: MsgGetDeviceInfo: cannot get temperature");
|
||||
}
|
||||
|
||||
if ((m_deviceParams->m_type != DeviceLimeSDRParams::LimeMini)
|
||||
&& (m_deviceParams->m_type != DeviceLimeSDRParams::LimeUndefined))
|
||||
{
|
||||
if (m_deviceParams->getDevice() && (LMS_GPIORead(m_deviceParams->getDevice(), &gpioPins, 1) != 0)) {
|
||||
qDebug("LimeSDRMIMO::handleMessage: MsgGetDeviceInfo: cannot get GPIO pins values");
|
||||
}
|
||||
}
|
||||
|
||||
// send to oneself
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp, gpioPins);
|
||||
getMessageQueueToGUI()->push(report);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
@ -571,7 +654,6 @@ bool LimeSDRMIMO::applySettings(const LimeSDRMIMOSettings& settings, bool force)
|
||||
|
||||
qDebug() << "LimeSDRMIMO::applySettings: common:"
|
||||
<< " m_devSampleRate: " << settings.m_devSampleRate
|
||||
<< " m_LOppmTenths: " << settings.m_LOppmTenths
|
||||
<< " m_gpioDir: " << settings.m_gpioDir
|
||||
<< " m_gpioPins: " << settings.m_gpioPins
|
||||
<< " m_extClock: " << settings.m_extClock
|
||||
|
||||
@ -67,14 +67,22 @@ public:
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
static MsgGetStreamInfo* create()
|
||||
bool getRxElseTx() const { return m_rxElseTx; }
|
||||
uint32_t getChannel() const { return m_channel; }
|
||||
|
||||
static MsgGetStreamInfo* create(bool rxElseTx, uint32_t channel)
|
||||
{
|
||||
return new MsgGetStreamInfo();
|
||||
return new MsgGetStreamInfo(rxElseTx, channel);
|
||||
}
|
||||
|
||||
private:
|
||||
MsgGetStreamInfo() :
|
||||
Message()
|
||||
bool m_rxElseTx;
|
||||
uint32_t m_channel;
|
||||
|
||||
MsgGetStreamInfo(bool rxElseTx, uint32_t channel) :
|
||||
Message(),
|
||||
m_rxElseTx(rxElseTx),
|
||||
m_channel(channel)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@ -276,6 +276,9 @@ bool LimeSDRMIMOGUI::handleMessage(const Message& message)
|
||||
|
||||
void LimeSDRMIMOGUI::displaySettings()
|
||||
{
|
||||
updateFrequencyLimits();
|
||||
updateLPFLimits();
|
||||
|
||||
if (m_rxElseTx)
|
||||
{
|
||||
ui->antenna->blockSignals(true);
|
||||
@ -391,7 +394,7 @@ void LimeSDRMIMOGUI::displaySettings()
|
||||
ui->lpFIREnable->setChecked(m_settings.m_lpfFIREnableTx0);
|
||||
ui->lpFIR->setValue(m_settings.m_lpfFIRBWTx0 / 1000);
|
||||
ui->gain->setValue(m_settings.m_gainTx0);
|
||||
ui->gainText->setText(tr("%1dB").arg(m_settings.m_gainTx0));
|
||||
ui->gainText->setText(tr("%1").arg(m_settings.m_gainTx0));
|
||||
ui->antenna->setCurrentIndex((int) m_settings.m_antennaPathTx0);
|
||||
}
|
||||
else if (m_streamIndex == 1)
|
||||
@ -400,7 +403,7 @@ void LimeSDRMIMOGUI::displaySettings()
|
||||
ui->lpFIREnable->setChecked(m_settings.m_lpfFIREnableTx1);
|
||||
ui->lpFIR->setValue(m_settings.m_lpfFIRBWTx1 / 1000);
|
||||
ui->gain->setValue(m_settings.m_gainTx1);
|
||||
ui->gainText->setText(tr("%1dB").arg(m_settings.m_gainTx1));
|
||||
ui->gainText->setText(tr("%1").arg(m_settings.m_gainTx1));
|
||||
ui->antenna->setCurrentIndex((int) m_settings.m_antennaPathTx1);
|
||||
}
|
||||
}
|
||||
@ -713,7 +716,7 @@ void LimeSDRMIMOGUI::updateStatus()
|
||||
}
|
||||
else
|
||||
{
|
||||
LimeSDRMIMO::MsgGetStreamInfo* message = LimeSDRMIMO::MsgGetStreamInfo::create();
|
||||
LimeSDRMIMO::MsgGetStreamInfo* message = LimeSDRMIMO::MsgGetStreamInfo::create(m_rxElseTx, m_streamIndex);
|
||||
m_limeSDRMIMO->getInputMessageQueue()->push(message);
|
||||
m_statusCounter = 0;
|
||||
}
|
||||
@ -724,12 +727,8 @@ void LimeSDRMIMOGUI::updateStatus()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_deviceUISet->m_deviceAPI->isBuddyLeader())
|
||||
{
|
||||
LimeSDRMIMO::MsgGetDeviceInfo* message = LimeSDRMIMO::MsgGetDeviceInfo::create();
|
||||
m_limeSDRMIMO->getInputMessageQueue()->push(message);
|
||||
}
|
||||
|
||||
LimeSDRMIMO::MsgGetDeviceInfo* message = LimeSDRMIMO::MsgGetDeviceInfo::create();
|
||||
m_limeSDRMIMO->getInputMessageQueue()->push(message);
|
||||
m_deviceStatusCounter = 0;
|
||||
}
|
||||
}
|
||||
@ -754,6 +753,7 @@ void LimeSDRMIMOGUI::on_spectrumSide_currentIndexChanged(int index)
|
||||
m_deviceUISet->m_deviceAPI->setSpectrumSinkInput(m_spectrumRxElseTx, m_spectrumStreamIndex);
|
||||
m_deviceUISet->setSpectrumScalingFactor(m_spectrumRxElseTx ? SDR_RX_SCALEF : SDR_TX_SCALEF);
|
||||
updateSampleRateAndFrequency();
|
||||
updateLPFLimits();
|
||||
}
|
||||
|
||||
void LimeSDRMIMOGUI::on_spectrumIndex_currentIndexChanged(int index)
|
||||
@ -797,21 +797,14 @@ void LimeSDRMIMOGUI::on_record_toggled(bool checked)
|
||||
void LimeSDRMIMOGUI::on_centerFrequency_changed(quint64 value)
|
||||
{
|
||||
if (m_rxElseTx) {
|
||||
m_settings.m_rxCenterFrequency = value * 1000;
|
||||
setRxCenterFrequencySetting(value);
|
||||
} else {
|
||||
m_settings.m_txCenterFrequency = value * 1000;
|
||||
setTxCenterFrequencySetting(value);
|
||||
}
|
||||
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
void LimeSDRMIMOGUI::on_LOppm_valueChanged(int value)
|
||||
{
|
||||
ui->LOppmText->setText(QString("%1").arg(QString::number(value/10.0, 'f', 1)));
|
||||
m_settings.m_LOppmTenths = value;
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
void LimeSDRMIMOGUI::on_ncoEnable_toggled(bool checked)
|
||||
{
|
||||
if (m_rxElseTx)
|
||||
|
||||
@ -114,7 +114,6 @@ private slots:
|
||||
void on_startStopTx_toggled(bool checked);
|
||||
void on_record_toggled(bool checked);
|
||||
void on_centerFrequency_changed(quint64 value);
|
||||
void on_LOppm_valueChanged(int value);
|
||||
void on_ncoEnable_toggled(bool checked);
|
||||
void on_ncoFrequency_changed(qint64 value);
|
||||
void on_dcOffset_toggled(bool checked);
|
||||
|
||||
@ -394,52 +394,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="LOppm_layout">
|
||||
<item>
|
||||
<widget class="QLabel" name="LOppmLabel">
|
||||
<property name="text">
|
||||
<string>LO ppm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="LOppm">
|
||||
<property name="toolTip">
|
||||
<string>Local Oscillator ppm correction</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-20</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="LOppmText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>26</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-0.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="topMargin">
|
||||
@ -925,7 +879,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Automatic global gain (dB)</string>
|
||||
<string>Automatic global gain</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>70</number>
|
||||
@ -953,7 +907,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Automatic global gain</string>
|
||||
<string>Automatic global gain (dB)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>20</string>
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
const PluginDescriptor LimeSDRMIMOPlugin::m_pluginDescriptor = {
|
||||
QString("LimeSDR"),
|
||||
QString("LimeSDR MIMO"),
|
||||
QString("5.4.0"),
|
||||
QString("5.5.0"),
|
||||
QString("(c) Edouard Griffiths, F4EXB"),
|
||||
QString("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
|
||||
@ -26,8 +26,7 @@ LimeSDRMIMOSettings::LimeSDRMIMOSettings()
|
||||
|
||||
void LimeSDRMIMOSettings::resetToDefaults()
|
||||
{
|
||||
m_devSampleRate = 5000000;
|
||||
m_LOppmTenths = 0;
|
||||
m_devSampleRate = 3200000;
|
||||
m_gpioDir = 0;
|
||||
m_gpioPins = 0;
|
||||
m_extClock = false;
|
||||
@ -94,7 +93,6 @@ QByteArray LimeSDRMIMOSettings::serialize() const
|
||||
SimpleSerializer s(1);
|
||||
|
||||
s.writeS32(1, m_devSampleRate);
|
||||
s.writeS32(2, m_LOppmTenths);
|
||||
s.writeU32(3, m_gpioDir);
|
||||
s.writeU32(4, m_gpioPins);
|
||||
s.writeBool(5, m_extClock);
|
||||
@ -174,7 +172,6 @@ bool LimeSDRMIMOSettings::deserialize(const QByteArray& data)
|
||||
uint32_t uintval;
|
||||
|
||||
d.readS32(1, &m_devSampleRate, 5000000);
|
||||
d.readS32(2, &m_LOppmTenths, 0);
|
||||
d.readU32(3, &uintval, 0);
|
||||
m_gpioDir = uintval & 0xFF;
|
||||
d.readU32(4, &uintval, 0);
|
||||
|
||||
@ -53,7 +53,6 @@ struct LimeSDRMIMOSettings
|
||||
|
||||
// General
|
||||
qint32 m_devSampleRate;
|
||||
qint32 m_LOppmTenths;
|
||||
uint8_t m_gpioDir; //!< GPIO pin direction LSB first; 0 input, 1 output
|
||||
uint8_t m_gpioPins; //!< GPIO pins to write; LSB first
|
||||
bool m_extClock; //!< True if external clock source
|
||||
|
||||
@ -51,35 +51,35 @@ void LimeSDRMIThread::startWork()
|
||||
return; // return if running already
|
||||
}
|
||||
|
||||
if (m_stream0)
|
||||
int ret[2];
|
||||
|
||||
ret[0] = LMS_StartStream(m_stream0);
|
||||
ret[1] = LMS_StartStream(m_stream1);
|
||||
|
||||
if (ret[0] < 0)
|
||||
{
|
||||
if (LMS_StartStream(m_stream0) < 0)
|
||||
{
|
||||
qCritical("LimeSDRMIThread::startWork: could not start stream 0");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(50000);
|
||||
qDebug("LimeSDRMIThread::startWork: stream 0 started");
|
||||
}
|
||||
qCritical("LimeSDRMIThread::startWork: could not start stream 0");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("LimeSDRMIThread::startWork: stream 0 started");
|
||||
}
|
||||
|
||||
if (m_stream1)
|
||||
{
|
||||
if (LMS_StartStream(m_stream1) < 0)
|
||||
if (ret[1] < 0)
|
||||
{
|
||||
qCritical("LimeSDRMIThread::startWork: could not start stream 1");
|
||||
LMS_StopStream(m_stream0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(50000);
|
||||
qDebug("LimeSDRMIThread::startWork: stream 1 started");
|
||||
qDebug("LimeSDRMIThread::startWork: stream 0 started");
|
||||
}
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
m_startWaitMutex.lock();
|
||||
start();
|
||||
|
||||
@ -98,32 +98,27 @@ void LimeSDRMIThread::stopWork()
|
||||
|
||||
m_running = false;
|
||||
wait();
|
||||
int ret[2];
|
||||
|
||||
if (m_stream0)
|
||||
{
|
||||
if (LMS_StopStream(m_stream0) < 0)
|
||||
{
|
||||
qCritical("LimeSDRInputThread::stopWork: could not stop stream 0");
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(50000);
|
||||
qDebug("LimeSDRInputThread::stopWork: stream 0 stopped");
|
||||
}
|
||||
ret[0] = LMS_StopStream(m_stream0);
|
||||
ret[1] = LMS_StopStream(m_stream1);
|
||||
|
||||
if (ret[0] < 0) {
|
||||
qCritical("LimeSDRInputThread::stopWork: could not stop stream 0");
|
||||
} else {
|
||||
qDebug("LimeSDRInputThread::stopWork: stream 0 stopped");
|
||||
}
|
||||
|
||||
if (m_stream1)
|
||||
{
|
||||
if (LMS_StopStream(m_stream1) < 0)
|
||||
{
|
||||
if (ret[1] < 0) {
|
||||
qCritical("LimeSDRInputThread::stopWork: could not stop stream 1");
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(50000);
|
||||
} else {
|
||||
qDebug("LimeSDRInputThread::stopWork: stream 1 stopped");
|
||||
}
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
}
|
||||
|
||||
void LimeSDRMIThread::setLog2Decimation(unsigned int log2_decim)
|
||||
@ -138,57 +133,47 @@ unsigned int LimeSDRMIThread::getLog2Decimation() const
|
||||
|
||||
void LimeSDRMIThread::run()
|
||||
{
|
||||
int res;
|
||||
|
||||
lms_stream_meta_t metadata; //Use metadata for additional control over sample receive function behaviour
|
||||
lms_stream_meta_t metadata; //Use metadata for additional control over sample receive function behaviour
|
||||
metadata.flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
|
||||
metadata.waitForTimestamp = false; //Do not wait for specific timestamps
|
||||
int lengths[2];
|
||||
int res[2];
|
||||
|
||||
m_running = true;
|
||||
m_startWaiter.wakeAll();
|
||||
|
||||
while (m_running)
|
||||
while (m_running && m_stream0)
|
||||
{
|
||||
if (m_stream0)
|
||||
{
|
||||
res = LMS_RecvStream(m_stream0, (void *) m_buf[0], DeviceLimeSDR::blockSize, &metadata, 1000);
|
||||
res[0] = LMS_RecvStream(m_stream0, (void *) m_buf0, DeviceLimeSDR::blockSize, &metadata, 1000);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
qCritical("LimeSDRMIThread::run read stream 0 error: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
lengths[0] = channelCallback(m_buf[0], 2*res, 0);
|
||||
}
|
||||
else
|
||||
if (res[0] < 0)
|
||||
{
|
||||
std::fill(m_convertBuffer[0].begin(), m_convertBuffer[0].end(), Sample{0,0});
|
||||
lengths[0] = m_convertBuffer[0].size() / (1<<m_log2Decim);
|
||||
qCritical("LimeSDRMIThread::run read stream 0 error: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_stream1)
|
||||
{
|
||||
res = LMS_RecvStream(m_stream1, (void *) m_buf[1], DeviceLimeSDR::blockSize, &metadata, 1000);
|
||||
res[1] = LMS_RecvStream(m_stream1, (void *) m_buf1, DeviceLimeSDR::blockSize, &metadata, 1000);
|
||||
|
||||
if (res < 0)
|
||||
if (res[1] < 0)
|
||||
{
|
||||
qCritical("LimeSDRMIThread::run read stream 1 error: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
lengths[1] = channelCallback(m_buf[1], 2*res, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::fill(m_convertBuffer[1].begin(), m_convertBuffer[1].end(), Sample{0,0});
|
||||
lengths[1] = m_convertBuffer[1].size() / (1<<m_log2Decim);
|
||||
std::fill(m_buf1, m_buf1 + 2*DeviceLimeSDR::blockSize, 0);
|
||||
res[1] = DeviceLimeSDR::blockSize;
|
||||
}
|
||||
|
||||
lengths[0] = channelCallback(m_buf0, 2*res[0], 0);
|
||||
lengths[1] = channelCallback(m_buf1, 2*res[1], 1);
|
||||
|
||||
if (lengths[0] == lengths[1])
|
||||
{
|
||||
qDebug("LimeSDRMIThread::run: writeSync %d samples", lengths[0]);
|
||||
//qDebug("LimeSDRMIThread::run: writeSync %d samples", lengths[0]);
|
||||
m_sampleFifo->writeSync(m_vBegin, lengths[0]);
|
||||
}
|
||||
else
|
||||
|
||||
@ -54,7 +54,8 @@ private:
|
||||
|
||||
lms_stream_t* m_stream0;
|
||||
lms_stream_t* m_stream1;
|
||||
qint16 m_buf[2][2*DeviceLimeSDR::blockSize];
|
||||
qint16 m_buf0[2*DeviceLimeSDR::blockSize];
|
||||
qint16 m_buf1[2*DeviceLimeSDR::blockSize];
|
||||
SampleVector m_convertBuffer[2];
|
||||
std::vector<SampleVector::const_iterator> m_vBegin;
|
||||
SampleMIFifo* m_sampleFifo;
|
||||
|
||||
@ -48,23 +48,24 @@ void LimeSDRMOThread::startWork()
|
||||
return; // return if running already
|
||||
}
|
||||
|
||||
if (m_stream0)
|
||||
int ret[2];
|
||||
|
||||
ret[0] = LMS_StartStream(m_stream0);
|
||||
ret[1] = LMS_StartStream(m_stream1);
|
||||
|
||||
if (ret[0] < 0)
|
||||
{
|
||||
if (LMS_StartStream(m_stream0) < 0)
|
||||
{
|
||||
qCritical("LimeSDROutputThread::startWork: could not start stream 0");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(50000);
|
||||
qDebug("LimeSDROutputThread::startWork: stream 0 started");
|
||||
}
|
||||
qCritical("LimeSDROutputThread::startWork: could not start stream 0");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("LimeSDROutputThread::startWork: stream 0 started");
|
||||
}
|
||||
|
||||
if (m_stream1)
|
||||
{
|
||||
if (LMS_StartStream(m_stream1) < 0)
|
||||
if (ret[1] < 0)
|
||||
{
|
||||
qCritical("LimeSDROutputThread::startWork: could not start stream 1");
|
||||
LMS_StopStream(m_stream0);
|
||||
@ -72,11 +73,11 @@ void LimeSDRMOThread::startWork()
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(50000);
|
||||
qDebug("LimeSDROutputThread::startWork: stream 1 started");
|
||||
}
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
m_startWaitMutex.lock();
|
||||
start();
|
||||
|
||||
@ -95,32 +96,29 @@ void LimeSDRMOThread::stopWork()
|
||||
|
||||
m_running = false;
|
||||
wait();
|
||||
int ret[2];
|
||||
|
||||
if (m_stream0)
|
||||
ret[0] = LMS_StopStream(m_stream0);
|
||||
ret[1] = LMS_StopStream(m_stream1);
|
||||
|
||||
if (ret[0] < 0)
|
||||
{
|
||||
if (LMS_StopStream(m_stream0) < 0)
|
||||
{
|
||||
qCritical("LimeSDROutputThread::stopWork: could not stop stream 0");
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(50000);
|
||||
qDebug("LimeSDROutputThread::stopWork: stream 0 stopped");
|
||||
}
|
||||
qCritical("LimeSDROutputThread::stopWork: could not stop stream 0");
|
||||
} else {
|
||||
qDebug("LimeSDROutputThread::stopWork: stream 0 stopped");
|
||||
}
|
||||
|
||||
if (m_stream1)
|
||||
{
|
||||
if (LMS_StopStream(m_stream1) < 0)
|
||||
if (ret[1] < 0)
|
||||
{
|
||||
qCritical("LimeSDROutputThread::stopWork: could not stop stream 1");
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(50000);
|
||||
} else {
|
||||
qDebug("LimeSDROutputThread::stopWork: stream 1 stopped");
|
||||
}
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
}
|
||||
|
||||
void LimeSDRMOThread::setLog2Interpolation(unsigned int log2Interp)
|
||||
@ -136,47 +134,42 @@ unsigned int LimeSDRMOThread::getLog2Interpolation() const
|
||||
|
||||
void LimeSDRMOThread::run()
|
||||
{
|
||||
int res;
|
||||
|
||||
lms_stream_meta_t metadata; //Use metadata for additional control over sample receive function behaviour
|
||||
metadata.flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
|
||||
metadata.waitForTimestamp = false; //Do not wait for specific timestamps
|
||||
|
||||
m_running = true;
|
||||
m_startWaiter.wakeAll();
|
||||
int res[2];
|
||||
|
||||
while (m_running)
|
||||
{
|
||||
callback(m_buf, DeviceLimeSDR::blockSize);
|
||||
|
||||
res[0] = LMS_SendStream(m_stream0, (void *) &m_buf[0], DeviceLimeSDR::blockSize, &metadata, 1000000);
|
||||
|
||||
if (m_stream0)
|
||||
if (res[0] < 0)
|
||||
{
|
||||
res = LMS_SendStream(m_stream0, (void *) &m_buf[0], DeviceLimeSDR::blockSize, &metadata, 1000000);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
qCritical("LimeSDROutputThread::run stream 0 write error: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
else if (res != DeviceLimeSDR::blockSize)
|
||||
{
|
||||
qDebug("LimeSDROutputThread::run stream 0 written %d/%d samples", res, DeviceLimeSDR::blockSize);
|
||||
}
|
||||
qCritical("LimeSDROutputThread::run stream 0 write error: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
else if (res[0] != DeviceLimeSDR::blockSize)
|
||||
{
|
||||
qDebug("LimeSDROutputThread::run stream 0 written %d/%u samples", res[0], DeviceLimeSDR::blockSize);
|
||||
}
|
||||
|
||||
if (m_stream1)
|
||||
{
|
||||
res = LMS_SendStream(m_stream1, (void *) &m_buf[2*DeviceLimeSDR::blockSize], DeviceLimeSDR::blockSize, &metadata, 1000000);
|
||||
res[1] = LMS_SendStream(m_stream1, (void *) &m_buf[2*DeviceLimeSDR::blockSize], DeviceLimeSDR::blockSize, &metadata, 1000000);
|
||||
|
||||
if (res < 0)
|
||||
if (res[1] < 0)
|
||||
{
|
||||
qCritical("LimeSDROutputThread::run stream 1 write error: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
else if (res != DeviceLimeSDR::blockSize)
|
||||
else if (res[1] != DeviceLimeSDR::blockSize)
|
||||
{
|
||||
qDebug("LimeSDROutputThread::run stream 1 written %d/%d samples", res, DeviceLimeSDR::blockSize);
|
||||
qDebug("LimeSDROutputThread::run stream 1 written %d/%u samples", res[1], DeviceLimeSDR::blockSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user