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:
commit
0c04560b3c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user