Post Go back to editing

Pluto SDR iiostream missing data

Category: Software
Product Number: ADALM-PLUTO
Software Version: v0.35

Hi,

I am trying to capture the RX samples from PLUTO SDR and save them to a file on my PC.

I simply modified the "ad9361-iiostream.c" example to write the RX buffer contents into a file instead of swapping I and Q.

https://github.com/analogdevicesinc/libiio/blob/master/examples/ad9361-iiostream.c

However, it seemed that some IQ samples were always lost at every iteration of the while loop.

What should I do to avoid date drops and capture the RX stream continuously? 

// Refill RX buffer
nbytes_rx = iio_buffer_refill(rxbuf);
if (nbytes_rx < 0) { printf("Error refilling buf %d\n",(int) nbytes_rx); shutdown(); }

// READ: Get pointers to RX buf and read IQ from RX buf port 0
p_inc = iio_buffer_step(rxbuf);
p_end = iio_buffer_end(rxbuf);
/*
for (p_dat = (char *)iio_buffer_first(rxbuf, rx0_i); p_dat < p_end; p_dat += p_inc) {
// Example: swap I and Q
const int16_t i = ((int16_t*)p_dat)[0]; // Real (I)
const int16_t q = ((int16_t*)p_dat)[1]; // Imag (Q)
((int16_t*)p_dat)[0] = q;
((int16_t*)p_dat)[1] = i;
}
*/
p_dat = (char*)iio_buffer_first(rxbuf, rx0_i);
fwrite(p_dat, 1, p_end - p_dat, fdo);

  • The pluto features a ring-buffer system that prevents losing samples in between samples. Basically when a buffer is created, a number of kernel buffers of the same size as the original buffer is allocated in the hardware. These kernel buffers save data continually from the ADC. More info here: https://wiki.analog.com/resources/tools-software/linux-software/libiio_internals?s[]=kernel&s[]=buffers#high-speed_mmap_interface

    As long as we are consuming (pulling) data faster than we are generating, the data should be continous. If not, the buffers eventually fill up and samples are dropped until a new buffer is freed(pulled). The symptoms of this would be: the first n buffers are continous, and then you have sample drops - n=4 by default. If you are consuming data from a remote context, the data needs to be transferred over the USB2.0 link to the PC which can be a bottleneck if the sample rate is higher than the USB 2.0 throughput. 

    Are you getting the same sample drops with lower sample rates ?

    -Adrian

  • I got the same sample drops with the sample rate of 2.5MHz, that is nearly the bandwidth of our target baseband signal. The USB 2.0 link might be a bottleneck, but int16 * 2 * 2.5MHz is much lower than the transfer rate that the USB 2.0 can handle.

  • According to my calculations you would need 2.5 *2(bytes/sample) * 2 (I/Q) * 2(Rx/Tx) * 8(bits) = 160Mbps

    I talked to the libiio developer and here is his response:
    If you do a speed test, iio_readdev -B -u usb:2.8.5 -b 8192 cf-ad9361-lpc voltage0 voltage1  you get about 18 MiB/s, which is about 144 Mbps
    If you increase the block sizes to 32k, you get a throughput of around 22 MiB/s, which is about 176 Mbps ,so in the first case you would definitely lose samples, in the second case you'd most likely lose samples from time to time, unless you have a big enough number of buffers
    -Adrian
  • I did a speed test and got the same 18 MiB/s. Since I only need to read the RX sample stream, the TX part was removed from ad9361-iiostream.c. It saved some USB 2.0 bandwidth, but I got the same sample drops. It seemed I need to find another SDR option for our project.