From ccb156329911c94a18897778d28f410978f04bdf Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 10 Sep 2017 16:58:48 +0200 Subject: [PATCH] PlutoSDR input: corrected I/Q loop processing as interleaved and not I/Q sample block --- devices/plutosdr/deviceplutosdrbox.cpp | 28 +++++++++++++++ .../plutosdrinput/plutosdrinput.cpp | 8 ++--- .../plutosdrinput/plutosdrinputthread.cpp | 35 +++++++++++++------ .../plutosdrinput/plutosdrinputthread.h | 9 ++--- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/devices/plutosdr/deviceplutosdrbox.cpp b/devices/plutosdr/deviceplutosdrbox.cpp index 523b8f02f..085924ee2 100644 --- a/devices/plutosdr/deviceplutosdrbox.cpp +++ b/devices/plutosdr/deviceplutosdrbox.cpp @@ -41,6 +41,14 @@ DevicePlutoSDRBox::DevicePlutoSDRBox(const std::string& uri) : if (m_valid) { getXO(); setTracking(); +// int nb_channels = iio_device_get_channels_count(m_devRx); +// for (int i = 0; i < nb_channels; i++) { +// iio_channel_disable(iio_device_get_channel(m_devRx, i)); +// } +// nb_channels = iio_device_get_channels_count(m_devTx); +// for (int i = 0; i < nb_channels; i++) { +// iio_channel_disable(iio_device_get_channel(m_devTx, i)); +// } } } @@ -213,6 +221,16 @@ bool DevicePlutoSDRBox::openRx() if (m_chnRx0) { iio_channel_enable(m_chnRx0); + const struct iio_data_format *df = iio_channel_get_data_format(m_chnRx0); + qDebug("DevicePlutoSDRBox::openRx: length: %u bits: %u shift: %u signed: %s be: %s with_scale: %s scale: %lf repeat: %u", + df->length, + df->bits, + df->shift, + df->is_signed ? "true" : "false", + df->is_be ? "true" : "false", + df->with_scale? "true" : "false", + df->scale, + df->repeat); return true; } else { std::cerr << "DevicePlutoSDRBox::openRx: failed" << std::endl; @@ -228,6 +246,16 @@ bool DevicePlutoSDRBox::openTx() if (m_chnTx0) { iio_channel_enable(m_chnTx0); + const struct iio_data_format *df = iio_channel_get_data_format(m_chnTx0); + qDebug("DevicePlutoSDRBox::openTx: length: %u bits: %u shift: %u signed: %s be: %s with_scale: %s scale: %lf repeat: %u", + df->length, + df->bits, + df->shift, + df->is_signed ? "true" : "false", + df->is_be ? "true" : "false", + df->with_scale? "true" : "false", + df->scale, + df->repeat); return true; } else { std::cerr << "DevicePlutoSDRBox::openTx: failed" << std::endl; diff --git a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp index a108dea71..c11606f90 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp @@ -26,7 +26,7 @@ #include "plutosdrinput.h" #include "plutosdrinputthread.h" -#define PLUTOSDR_BLOCKSIZE (128*1024) //complex samples per buffer (must be multiple of 64) +#define PLUTOSDR_BLOCKSIZE_SAMPLES (128*1024) //complex samples per buffer (must be multiple of 64) MESSAGE_CLASS_DEFINITION(PlutoSDRInput::MsgConfigurePlutoSDR, Message) MESSAGE_CLASS_DEFINITION(PlutoSDRInput::MsgFileRecord, Message) @@ -70,7 +70,7 @@ bool PlutoSDRInput::start() // start / stop streaming is done in the thread. - if ((m_plutoSDRInputThread = new PlutoSDRInputThread(PLUTOSDR_BLOCKSIZE, m_deviceShared.m_deviceParams->getBox(), &m_sampleFifo)) == 0) + if ((m_plutoSDRInputThread = new PlutoSDRInputThread(PLUTOSDR_BLOCKSIZE_SAMPLES, m_deviceShared.m_deviceParams->getBox(), &m_sampleFifo)) == 0) { qFatal("PlutoSDRInput::start: cannot create thread"); stop(); @@ -153,7 +153,7 @@ bool PlutoSDRInput::handleMessage(const Message& message) bool PlutoSDRInput::openDevice() { - if (!m_sampleFifo.setSize(PLUTOSDR_BLOCKSIZE)) + if (!m_sampleFifo.setSize(PLUTOSDR_BLOCKSIZE_SAMPLES)) { qCritical("PlutoSDRInput::openDevice: could not allocate SampleFifo"); return false; @@ -198,7 +198,7 @@ bool PlutoSDRInput::openDevice() // acquire the channel DevicePlutoSDRBox *plutoBox = m_deviceShared.m_deviceParams->getBox(); plutoBox->openRx(); - m_plutoRxBuffer = plutoBox->createRxBuffer(PLUTOSDR_BLOCKSIZE, false); + m_plutoRxBuffer = plutoBox->createRxBuffer(PLUTOSDR_BLOCKSIZE_SAMPLES*2, false); // PlutoSDR buffer size is counted in number of I or Q samples not the combination return true; } diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputthread.cpp b/plugins/samplesource/plutosdrinput/plutosdrinputthread.cpp index cd67d63ce..629faba3e 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputthread.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinputthread.cpp @@ -18,19 +18,22 @@ #include "plutosdrinputsettings.h" #include "plutosdrinputthread.h" -PlutoSDRInputThread::PlutoSDRInputThread(uint32_t blocksize, DevicePlutoSDRBox* plutoBox, SampleSinkFifo* sampleFifo, QObject* parent) : +#include "iio.h" + +PlutoSDRInputThread::PlutoSDRInputThread(uint32_t blocksizeSamples, DevicePlutoSDRBox* plutoBox, SampleSinkFifo* sampleFifo, QObject* parent) : QThread(parent), m_running(false), m_plutoBox(plutoBox), - m_blockSize(blocksize), - m_convertBuffer(blocksize), - m_sampleFifo(sampleFifo), + m_blockSizeSamples(blocksizeSamples), + m_convertBuffer(blocksizeSamples), m_convertIt(m_convertBuffer.begin()), + m_sampleFifo(sampleFifo), m_log2Decim(0), m_fcPos(PlutoSDRInputSettings::FC_POS_CENTER), m_phasor(0) { - m_buf = new qint16[blocksize*(sizeof(Sample)/sizeof(qint16))]; + m_buf = new qint16[blocksizeSamples*(sizeof(Sample)/sizeof(qint16))]; + m_bufConv = new qint16[blocksizeSamples*(sizeof(Sample)/sizeof(qint16))]; } PlutoSDRInputThread::~PlutoSDRInputThread() @@ -78,7 +81,7 @@ void PlutoSDRInputThread::run() ssize_t nbytes_rx; char *p_dat, *p_end; std::ptrdiff_t p_inc; - int is; + int ihs; // half sample index (I then Q to make a sample) // Refill RX buffer nbytes_rx = m_plutoBox->rxBufferRefill(); @@ -87,16 +90,26 @@ void PlutoSDRInputThread::run() // READ: Get pointers to RX buf and read IQ from RX buf port 0 p_inc = m_plutoBox->rxBufferStep(); p_end = m_plutoBox->rxBufferEnd(); - is = 0; + ihs = 0; + +// qDebug("PlutoSDRInputThread::run: %ld samples read step: %ld", nbytes_rx / p_inc, p_inc); + // p_inc is 2 on a char* buffer therefore each iteration processes only the I or Q sample + // I and Q samples are processed one at a time + // conversion is not needed as samples are little endian for (p_dat = m_plutoBox->rxBufferFirst(); p_dat < p_end; p_dat += p_inc) { - memcpy(&m_buf[2*is], p_dat, 2*sizeof(int16_t)); - is++; +// m_buf[2*is] = ((int16_t *) p_dat)[0]; +// m_buf[2*is+1] = ((int16_t *) p_dat)[1]; +// memcpy(&m_buf[2*ihs], p_dat, 2*sizeof(int16_t)); + m_buf[ihs] = *((int16_t *) p_dat); +// iio_channel_convert(m_plutoBox->getRxChannel0(), (void *) &m_bufConv[2*ihs], (const void *) &m_buf[2*ihs]); +// iio_channel_convert(m_plutoBox->getRxChannel0(), (void *) &m_bufConv[ihs], (const void *) &m_buf[ihs]); + ihs++; } - //m_sampleFifo->write((unsigned char *) m_buf, is*2*sizeof(int16_t)); - convert(m_buf, 2 * m_blockSize); + m_sampleFifo->write((unsigned char *) m_buf, ihs*sizeof(int16_t)); + //convert(m_bufConv, 2 * m_blockSize); } m_running = false; diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputthread.h b/plugins/samplesource/plutosdrinput/plutosdrinputthread.h index 42035a0e6..f6373deb2 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputthread.h +++ b/plugins/samplesource/plutosdrinput/plutosdrinputthread.h @@ -48,11 +48,12 @@ private: bool m_running; DevicePlutoSDRBox *m_plutoBox; - int16_t *m_buf; // holds I+Q values of each sample - uint32_t m_blockSize; - SampleVector m_convertBuffer; - SampleSinkFifo* m_sampleFifo; + int16_t *m_buf; //!< holds I+Q values of each sample from devce + int16_t *m_bufConv; //!< holds I+Q values of each sample converted to host format via iio_channel_convert + uint32_t m_blockSizeSamples; //!< buffer sizes in number of (I,Q) samples + SampleVector m_convertBuffer; //!< vector of (I,Q) samples used for decimation and scaling conversion SampleVector::iterator m_convertIt; + SampleSinkFifo* m_sampleFifo; //!< DSP sample FIFO (I,Q) unsigned int m_log2Decim; // soft decimation int m_fcPos;