AnsweredAssumed Answered

LibIIO - interfacing FMCOMMS3 over the Ethernet

Question asked by sauka on Nov 30, 2017
Latest reply on Dec 7, 2017 by mhennerich

Dear engineers,

 

I have a question regarding network context of libiio, and TX operation. In my application I have strict requirement to send data to the RF frontend every 1ms, all baseband processing is done on my desktop Linux PC. I'm using Fmcomms3 board with ZC706 board, and I connect this board to my PC through 1Gbit-Ethernet.

 

My problem is that communication is too slow: in 5MHz bandwidth config (@7.68MHz bb clock), I try to send 7680 I-Q samples every 1ms, and it takes around 0.8-1ms (mainly because of blocking iio_buffer_push). I paste below my transmit() function, may be I'm doing something wrong.. Or, is there any way to improve communication?

 

void FMCommsImpl::tx_subframe(std::vector<std::complex<float>>& subframe) {
   uintptr_t dst_ptrI = (uintptr_t)iio_buffer_first(txbuf, tx_i);
   uintptr_t dst_ptrQ = (uintptr_t)iio_buffer_first(txbuf, tx_q);
   uintptr_t buf_end = (uintptr_t) iio_buffer_end(txbuf);

   ptrdiff_t buf_step = iio_buffer_step(txbuf);

   size_t iio_buf_size = (uintptr_t)iio_buffer_end(txbuf) - (uintptr_t)iio_buffer_start(txbuf);
   size_t sample_size = iio_device_get_sample_size(tx);
   assert(sample_size * subframe.size() <= iio_buf_size && "IIO buffer does not have sufficient capacity\n");


   for (auto it = subframe.begin(); it != subframe.end() &&
          (dst_ptrI < buf_end && dst_ptrQ < buf_end);
          ++it, dst_ptrI += buf_step, dst_ptrQ += buf_step)
   {
      static const float factor = 32767.0; // convert to fixed point representation
      short I = static_cast<short>(it->real() * factor);
      short Q = static_cast<short>(it->imag() * factor);
      iio_channel_convert_inverse(tx_i,
                  (void *)dst_ptrI, (const void *) &I);
      iio_channel_convert_inverse(tx_q,
                  (void *)dst_ptrQ, (const void *) &Q);
   }

   int ret = iio_buffer_push(txbuf);
   if (ret < 0)
      std::cerr << "FMCommsImpl::txSubframe - unable to push buffer\n";
}

 

And here is code snippet from my openDevice() function, regarding transmit channels:

     tx = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc");

     ...

     tx_i = iio_device_find_channel(tx, "voltage0", true)

     tx_q = iio_device_find_channel(tx, "voltage1", true)

     iio_channel_enable(tx_i);

     iio_channel_enable(tx_q);

     txbuf = iio_device_create_buffer(tx, 7680, false);

 

Any help is appreciated.

 

Pavel

 

Outcomes