Post Go back to editing

Get in RX the same values of TX

Hi people,

There is a way to send a data in the TX and receive the same in the RX?  I mean if I put a cable between TX A and RX A and send a value in I and another in Q, there is a way to get them back on the RX A I/Q?  I am developing a IEEE 802.15.4 transceiver, and for testing, at least in the begging would be nice to be able to do that, send something and get the same the other side.

I tried to change the ad9361-iiostream.c to send always the same data, RX and TX in the same frequency, and on the RX compare the received I/Q to see if was the same... but I didn't manage to do it.  Well it makes sense not being able to, the process is too fast, so the time you say send this and you start reading it is possible that you will not read the same thing you just sent, even more because, as far as I understood the buffers in the middle would make this  synchronization a nightmare, even with different threads for the send and receive.

Nevertheless, I would know if I can do it, somehow to be able to test my transceiver.

   Best regards...

          Daniel

  • Daniel,

    Yes there is. It's called BIST LOOPBACK.

    See here: FMCOMMS2/3/4/5 Advanced Plugin [Analog Devices Wiki]

    • Digital TX → Digital RX loopback : The loopback happens inside the AD9361/4 close to the internal digital interface block. The entire RF section is bypassed. This can be used to validate (monitor on RX) the digital samples/symbols sent to the device.

    root@analog:/sys/kernel/debug/iio/iio:device1# echo 1 > loopback

    -Michael

  • Hi Daniel,

    The things is that the format differs between Tx an Rx.

    On Rx it's 12-bit sign extended.

    On Tx it's also 12-bit signed but MSB aligned within the 16-word.

    So everything you transmit must be left shifted by 4 or multiplied by 32.

    See here: https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/software/basic_iq_datafiles#binary_format

    -Michael

  • Thanks Michael,

      It was exactly that what I wanted. Just one small clarification though... it seems it is loosing in precision... well that was somehow expected and in fact it is not a big deal!  The thing that is bothering me is that I am having a hard time to understanding how it works the receiving part. As in the example, I fill just the tx0_i, and try to read only the rx0_i... the result is strange. If I fill the tx0_i and try to read the rx0_i and rx0_q... seems quite better, everything it is there at least, but I don't know understand how to make sense of  the results.

    For the values, I am generating a sinusoid of 4 points for I and  Q is the same sinusoid, but shifted of 2 and multiplied by -1 (I made a lot of tests to try to find the logic ). I am attaching the smallchange.c (small changes over the standard  ad9361-iiostream.c ). By the way, I am using over the network, I don't think it makes any difference.... but who knows?!?!

    -> main:338: --- To Send Values ---

    -> main:346: i:0 I=0,Q=FFFF8001

    -> main:346: i:1 I=5A82,Q=FFFFA57E

    -> main:346: i:2 I=7FFF,Q=0

    -> main:346: i:3 I=5A82,Q=FFFFA57E

    -> main:346: i:4 I=0,Q=FFFF8001

    -> main:346: i:5 I=5A82,Q=FFFFA57E

    -> main:346: i:6 I=7FFF,Q=0

    -> main:346: i:7 I=5A82,Q=FFFFA57E

    -> main:346: i:8 I=0,Q=FFFF8001

    -> main:346: i:9 I=5A82,Q=FFFFA57E

    -> main:369: --- Received Values  rx0_i ---

    -> main:376: i:0 I_i=7FF,Q_i=0

    -> main:376: i:1 I_i=5A8,Q_i=FFFFFA57

    -> main:376: i:2 I_i=7FF,Q_i=0

    -> main:376: i:3 I_i=5A8,Q_i=FFFFFA57

    -> main:376: i:4 I_i=7FF,Q_i=0

    -> main:376: i:5 I_i=5A8,Q_i=FFFFFA57

    -> main:376: i:6 I_i=7FF,Q_i=0

    -> main:376: i:7 I_i=5A8,Q_i=FFFFFA57

    -> main:376: i:8 I_i=7FF,Q_i=0

    -> main:376: i:9 I_i=5A8,Q_i=FFFFFA57

    -> main:382: --- Received Values  rx0_q ---

    -> main:389: i:0 I_q=0,Q_q=5A8

    -> main:389: i:1 I_q=FFFFFA57,Q_q=7FF

    -> main:389: i:2 I_q=0,Q_q=5A8

    -> main:389: i:3 I_q=FFFFFA57,Q_q=7FF

    -> main:389: i:4 I_q=0,Q_q=5A8

    -> main:389: i:5 I_q=FFFFFA57,Q_q=7FF

    -> main:389: i:6 I_q=0,Q_q=5A8

    -> main:389: i:7 I_q=FFFFFA57,Q_q=7FF

    -> main:389: i:8 I_q=0,Q_q=5A8

    -> main:389: i:9 I_q=FFFFFA57,Q_q=7FF

        RX    3.15 MSmp, TX    3.15 MSmp

    Another fast question is, is there a way to reset the loopback buffer from the code? Sometimes I see that I get the results of the last run, what I am doing is to change the loopback to 0, run the code, chage it again to 1 to be sure it will work, I guess there is a smarter way of doing it .

    Best regards....

              Daniel

    smallchange.c.zip
  • Hi Michael,

      Thanks for the link that really answers the question about the loss in precision.  But there is a way to set the size of the buffer for the loopback? It seems the buffer is limited to 4 symbols.

       I spend some time trying to understand again and I perceived (yes I am kind of slow ) that in fact it just repeats some values, over and over. I changed the code to, instead of a sinusoid just send a number count and then the result is even clearer.... The loop back buffer has a size that I should set somewhere? I tried to find in the osciloscope but I didn't managed to. Any ideas?

    Just for the sake of the example, here, the RX buffer is a sequence of FE, FF, FC, FD:

    --- To Send Values ---

    i:0 I=0,Q=10 :: 100000

    i:1 I=20,Q=30 :: 300020

    i:2 I=40,Q=50 :: 500040

    i:3 I=60,Q=70 :: 700060

    i:4 I=80,Q=90 :: 900080

    i:5 I=A0,Q=B0 :: B000A0

    i:6 I=C0,Q=D0 :: D000C0

    i:7 I=E0,Q=F0 :: F000E0

    i:8 I=100,Q=110 :: 1100100

    i:9 I=120,Q=130 :: 1300120

    --- Received Values  rx0_i ---

    i:0 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:1 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    i:2 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:3 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    i:4 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:5 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    i:6 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:7 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    i:8 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:9 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    --------------------------

    ////////////////////////////////////

    If I change it to  my sinusoid again.... than the first time it flushes the old buffer (as expected), and after it gets locked into a sequence of the sinusoid. (0000, FFFF, FA82, 57E).

    //////////////////////////////////////

    --- To Send Values ---

    i:0 I=0,Q=10 :: 100000

    i:1 I=FFFFA820,Q=57E0 :: 57E0A820

    i:2 I=FFFFFFF0,Q=0 :: FFF0

    i:3 I=FFFFA820,Q=57E0 :: 57E0A820

    i:4 I=0,Q=10 :: 100000

    i:5 I=FFFFA820,Q=57E0 :: 57E0A820

    i:6 I=FFFFFFF0,Q=0 :: FFF0

    i:7 I=FFFFA820,Q=57E0 :: 57E0A820

    i:8 I=0,Q=10 :: 100000

    i:9 I=FFFFA820,Q=57E0 :: 57E0A820

    --- Received Values  rx0_i ---

    i:0 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:1 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    i:2 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:3 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    i:4 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:5 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    i:6 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:7 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

    i:8 I_i=FFFFFFFE,Q_i=FFFFFFFF :: FFFFFFFE

    i:9 I_i=FFFFFFFC,Q_i=FFFFFFFD :: FFFDFFFC

        RX     1.05 MSmp, TX     1.05 MSmp

    --- To Send Values ---

    i:0 I=0,Q=10 :: 100000

    i:1 I=FFFFA820,Q=57E0 :: 57E0A820

    i:2 I=FFFFFFF0,Q=0 :: FFF0

    i:3 I=FFFFA820,Q=57E0 :: 57E0A820

    i:4 I=0,Q=10 :: 100000

    i:5 I=FFFFA820,Q=57E0 :: 57E0A820

    i:6 I=FFFFFFF0,Q=0 :: FFF0

    i:7 I=FFFFA820,Q=57E0 :: 57E0A820

    i:8 I=0,Q=10 :: 100000

    i:9 I=FFFFA820,Q=57E0 :: 57E0A820

    --- Received Values  rx0_i ---

    i:0 I_i=FFFFFFFF,Q_i=0 :: FFFF

    i:1 I_i=FFFFFA82,Q_i=57E :: 57EFA82

    i:2 I_i=FFFFFFFF,Q_i=0 :: FFFF

    i:3 I_i=FFFFFA82,Q_i=57E :: 57EFA82

    i:4 I_i=FFFFFFFF,Q_i=0 :: FFFF

    i:5 I_i=FFFFFA82,Q_i=57E :: 57EFA82

    i:6 I_i=FFFFFFFF,Q_i=0 :: FFFF

    i:7 I_i=FFFFFA82,Q_i=57E :: 57EFA82

    i:8 I_i=FFFFFFFF,Q_i=0 :: FFFF

    i:9 I_i=FFFFFA82,Q_i=57E :: 57EFA82

  • Daniel,

    Don't confuse things - Loopback has nothing todo with buffers.

    Loopback happens on the interface level internal to the AD9361. No single bit will be lost.

    What you are seeing can be related to libiio buffers. There are cyclic buffers that repeat over and over again.

    Non-Cyclic streaming buffers, if you can't push fast enough you will also see that the last sample(s) will be repeated, until new data is pushed.

    So make your buffers big enough to reduce management overhead. If necessary you may need to reduce the sample rate.

    -Michael

  • Hi,

    Yes, the effect is pretty much the same as the loopback cable, except that the delay is slightly shorter and the received values will be exactly the same as the send values.

    If you want to feed back the data that you send out to your application why not simply store the data in your application itself?

    - Lars

  • OK sorry,

    What I meant to say was that when I read the rxbuf (iio_buffer_refill(rxbuf);) the only thing that is inside, the full content of the rxbuf, is a repetition of the same I and Q over and over.  What I understood was that the full I/Q  sent stream would be stored until it get read. Well, apparently it is not the case! I will try to decrease the frequency and increase the send and receive buffers... but if the values are not stored somehow, to be replayed it will be  more or less the same as putting the loop back cable no?

      Best regards...

               Daniel

  • Hi Lars,

      It is what I was (am) doing in my real code, but I felt, somehow, like cheating . This is why I asked if I could send and receive the same thing, to be as closely as possible to the, real final mechanisms I will use in the program.

    Well, IF, one day, I manage to do an usable RX/TX I will send you so that you can use as an example .

      Best regards...

               Daniel