Post Go back to editing

ad9371-iiostream.c example with multiple frequencies

Hello everyone.

I'm new to IIO and Analog Devices, so please be patient with me. I not sure if I'm missing something simple or fundamental. 

I have three frequencies that I need to stream data through.

Frequency1    ----                               -----

Frequency2             -----                                   ----------

Frequency3                       ----------                                  -------

Problem:

The receivers do not get all packages sent by AD93 when I switch between frequencies

Question 1: why ad9371-iiostream.c example calls  iio_buffer_push() function first , then loops through the buffer to write data using calls iio_buffer_step() iio_buffer_end() ? A strange concept , intuitively I would assume it should look like  

       // 1.  prepare the buffer - using iio_buffer_step() and iio_buffer_end()  functions

       // 2. then call iio_buffer_push() - to push the data to the device and transfer it through RF

instead ad9371-iiostream.c example does the opposite. I don't get that and I don't get how it works. How the AD93 device knows when to send the buffer to RF ? what triggers start of the physical RF signal?

Question 2: I switch the frequency in the beginning of the loop and it doesn't work as I would expect. What am I doing wrong?

My current solution:

I'm using this well documented example to stream data and it works well with one frequency.

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

I'm doing the frequency switch in the beginning of the loop. 

Is that a correct solution? if yes, then why am I loosing packages right after doing a frequency switch?

    while (!stop)
	{
myCustomSetFrequency(); // this is the only change I made in ad9371-iiostream.c example

ssize_t nbytes_rx, nbytes_tx; char *p_dat, *p_end; ptrdiff_t p_inc; // Schedule TX buffer nbytes_tx = iio_buffer_push(txbuf); if (nbytes_tx < 0) { printf("Error pushing buf %d\n", (int) nbytes_tx); shutdown(); }
// commented out because I don't need to read here
/* // 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; } */
// WRITE: Get pointers to TX buf and write IQ to TX buf port 0 p_inc = iio_buffer_step(txbuf); p_end = iio_buffer_end(txbuf); for (p_dat = (char *)iio_buffer_first(txbuf, tx0_i); p_dat < p_end; p_dat += p_inc) { // Example: fill with zeros // 12-bit sample needs to be MSB aligned so shift by 4 // wiki.analog.com/.../basic_iq_datafiles ((int16_t*)p_dat)[0] = 0 << 4; // Real (I) ((int16_t*)p_dat)[1] = 0 << 4; // Imag (Q) } // Sample counter increment and status output nrx += nbytes_rx / iio_device_get_sample_size(rx); ntx += nbytes_tx / iio_device_get_sample_size(tx); printf("\tRX %8.2f MSmp, TX %8.2f MSmp\n", nrx/1e6, ntx/1e6); }

I have defined my custom function to set the current frequency based on the business logic defined in another function myCustomGetCurrentFrequency(). This implementation changes the frequency only when the change is required.

function myCustomSetFrequency()

{

   long long new_frequency = myCustomGetCurrentFrequency();

   if(current_frequency != new_frequency )

   {

       current_frequency = new_frequency;

       iio_channel_attr_write_longlong(
            iio_device_find_channel(config.phy, "altvoltage1", true),
            "frequency",
            current_frequency);

   }

}

Thank you!