1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 01:55:48 -05:00

Merge pull request #605 from ubfx/plutosdr_iq_sampling

Fix libiio channel handling for IQ sampling with plutosdr
This commit is contained in:
f4exb 2020-08-19 13:13:45 +02:00 committed by GitHub
commit 0c04560b3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 43 deletions

View File

@ -40,7 +40,8 @@ DevicePlutoSDRBox::DevicePlutoSDRBox(const std::string& uri) :
m_devPhy(0), m_devPhy(0),
m_devRx(0), m_devRx(0),
m_devTx(0), m_devTx(0),
m_chnRx0(0), m_chnRx0i(0),
m_chnRx0q(0),
m_chnTx0i(0), m_chnTx0i(0),
m_chnTx0q(0), m_chnTx0q(0),
m_rxBuf(0), m_rxBuf(0),
@ -258,14 +259,15 @@ bool DevicePlutoSDRBox::openRx()
{ {
if (!m_valid) { return false; } if (!m_valid) { return false; }
if (!m_chnRx0) { if (!m_chnRx0i) {
m_chnRx0 = iio_device_find_channel(m_devRx, "voltage0", false); m_chnRx0i = iio_device_find_channel(m_devRx, "voltage0", false);
} }
if (m_chnRx0) { if (m_chnRx0i) {
iio_channel_enable(m_chnRx0); iio_channel_enable(m_chnRx0i);
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", const struct iio_data_format *df = iio_channel_get_data_format(m_chnRx0i);
qDebug("DevicePlutoSDRBox::openRx channel I: length: %u bits: %u shift: %u signed: %s be: %s with_scale: %s scale: %lf repeat: %u",
df->length, df->length,
df->bits, df->bits,
df->shift, df->shift,
@ -274,11 +276,34 @@ bool DevicePlutoSDRBox::openRx()
df->with_scale? "true" : "false", df->with_scale? "true" : "false",
df->scale, df->scale,
df->repeat); df->repeat);
return true;
} else { } else {
std::cerr << "DevicePlutoSDRBox::openRx: failed" << std::endl; std::cerr << "DevicePlutoSDRBox::openRx: failed" << std::endl;
return false; return false;
} }
if (!m_chnRx0q) {
m_chnRx0q = iio_device_find_channel(m_devRx, "voltage1", false);
}
if (m_chnRx0q) {
iio_channel_enable(m_chnRx0q);
const struct iio_data_format* df = iio_channel_get_data_format(m_chnRx0q);
qDebug("DevicePlutoSDRBox::openRx channel Q: 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;
return false;
}
} }
bool DevicePlutoSDRBox::openTx() bool DevicePlutoSDRBox::openTx()
@ -331,7 +356,8 @@ bool DevicePlutoSDRBox::openTx()
void DevicePlutoSDRBox::closeRx() void DevicePlutoSDRBox::closeRx()
{ {
if (m_chnRx0) { iio_channel_disable(m_chnRx0); } if (m_chnRx0i) { iio_channel_disable(m_chnRx0i); }
if (m_chnRx0q) { iio_channel_disable(m_chnRx0q); }
} }
void DevicePlutoSDRBox::closeTx() void DevicePlutoSDRBox::closeTx()
@ -435,7 +461,7 @@ char* DevicePlutoSDRBox::rxBufferEnd()
char* DevicePlutoSDRBox::rxBufferFirst() char* DevicePlutoSDRBox::rxBufferFirst()
{ {
if (m_rxBuf) { if (m_rxBuf) {
return (char *) iio_buffer_first(m_rxBuf, m_chnRx0); return (char *) iio_buffer_first(m_rxBuf, m_chnRx0i);
} else { } else {
return 0; return 0;
} }

View File

@ -85,7 +85,7 @@ public:
void deleteTxBuffer(); void deleteTxBuffer();
ssize_t getRxSampleSize(); ssize_t getRxSampleSize();
ssize_t getTxSampleSize(); ssize_t getTxSampleSize();
struct iio_channel *getRxChannel0() { return m_chnRx0; } struct iio_channel *getRxChannel0() { return m_chnRx0i; }
struct iio_channel *getTxChannel0I() { return m_chnTx0i; } struct iio_channel *getTxChannel0I() { return m_chnTx0i; }
struct iio_channel *getTxChannel0Q() { return m_chnTx0q; } struct iio_channel *getTxChannel0Q() { return m_chnTx0q; }
ssize_t rxBufferRefill(); ssize_t rxBufferRefill();
@ -119,7 +119,8 @@ private:
struct iio_device *m_devPhy; struct iio_device *m_devPhy;
struct iio_device *m_devRx; struct iio_device *m_devRx;
struct iio_device *m_devTx; struct iio_device *m_devTx;
struct iio_channel *m_chnRx0; struct iio_channel *m_chnRx0i;
struct iio_channel* m_chnRx0q;
struct iio_channel *m_chnTx0i; struct iio_channel *m_chnTx0i;
struct iio_channel *m_chnTx0q; struct iio_channel *m_chnTx0q;
struct iio_buffer *m_rxBuf; struct iio_buffer *m_rxBuf;

View File

@ -80,7 +80,7 @@ void PlutoSDRInputThread::run()
qDebug("PlutoSDRInputThread::run: rxBufferStep: %ld bytes", p_inc); qDebug("PlutoSDRInputThread::run: rxBufferStep: %ld bytes", p_inc);
qDebug("PlutoSDRInputThread::run: Rx sample size is %ld bytes", m_plutoBox->getRxSampleSize()); qDebug("PlutoSDRInputThread::run: Rx sample size is %ld bytes", m_plutoBox->getRxSampleSize());
qDebug("PlutoSDRInputThread::run: Tx sample size is %ld bytes", m_plutoBox->getTxSampleSize()); qDebug("PlutoSDRInputThread::run: Tx sample size is %ld bytes", m_plutoBox->getTxSampleSize());
qDebug("PlutoSDRInputThread::run: nominal nbytes_rx is %d bytes with 2 refills", m_blockSizeSamples*2); qDebug("PlutoSDRInputThread::run: nominal nbytes_rx is %d bytes with 1 refill", m_blockSizeSamples*4);
m_running = true; m_running = true;
m_startWaiter.wakeAll(); m_startWaiter.wakeAll();
@ -94,9 +94,9 @@ void PlutoSDRInputThread::run()
// Refill RX buffer // Refill RX buffer
nbytes_rx = m_plutoBox->rxBufferRefill(); nbytes_rx = m_plutoBox->rxBufferRefill();
if (nbytes_rx != m_blockSizeSamples*2) if (nbytes_rx != m_blockSizeSamples*4)
{ {
qWarning("PlutoSDRInputThread::run: error refilling buf (1) %d / %d",(int) nbytes_rx, (int) m_blockSizeSamples*2); qWarning("PlutoSDRInputThread::run: error refilling buf %d / %d",(int) nbytes_rx, (int) m_blockSizeSamples*4);
usleep(200000); usleep(200000);
continue; continue;
} }
@ -105,39 +105,15 @@ void PlutoSDRInputThread::run()
p_end = m_plutoBox->rxBufferEnd(); p_end = m_plutoBox->rxBufferEnd();
ihs = 0; ihs = 0;
// p_inc is 2 on a char* buffer therefore each iteration processes only the I or Q sample // p_inc is 4 on a char* buffer therefore each iteration processes a single IQ sample,
// I and Q samples are processed one after the other // I and Q each being two bytes
// conversion is not needed as samples are little endian // conversion is not needed as samples are little endian
for (p_dat = m_plutoBox->rxBufferFirst(); p_dat < p_end; p_dat += p_inc) for (p_dat = m_plutoBox->rxBufferFirst(); p_dat < p_end; p_dat += p_inc)
{ {
m_buf[ihs] = *((int16_t *) p_dat); m_buf[ihs++] = *((int16_t *) p_dat);
m_buf[ihs++] = *(((int16_t *) p_dat) + 1);
// iio_channel_convert(m_plutoBox->getRxChannel0(), (void *) &m_bufConv[ihs], (const void *) &m_buf[ihs]); // iio_channel_convert(m_plutoBox->getRxChannel0(), (void *) &m_bufConv[ihs], (const void *) &m_buf[ihs]);
ihs++;
}
// Refill RX buffer again - we still need twice more samples to complete since they come as I followed by Q
nbytes_rx = m_plutoBox->rxBufferRefill();
if (nbytes_rx != m_blockSizeSamples*2)
{
qWarning("PlutoSDRInputThread::run: error refilling buf (2) %d / %d",(int) nbytes_rx, (int) m_blockSizeSamples*2);
usleep(200000);
continue;
}
// READ: Get pointers to RX buf and read IQ from RX buf port 0
p_end = m_plutoBox->rxBufferEnd();
// 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 after the other
// conversion is not needed as samples are little endian
for (p_dat = m_plutoBox->rxBufferFirst(); p_dat < p_end; p_dat += p_inc)
{
m_buf[ihs] = *((int16_t *) p_dat);
// iio_channel_convert(m_plutoBox->getRxChannel0(), (void *) &m_bufConv[ihs], (const void *) &m_buf[ihs]);
ihs++;
} }
if (m_iqOrder) { if (m_iqOrder) {