Post Go back to editing

Local oscillator frequency sweep for ad9361 Transciever

Category: Software
Product Number: ad9361

Hey I need guidance on ad9361 Lo frequency sweep. To elaborate my query I have divided it into several sections as follows;

What I am doing

Currently I am working  to sweep the Local oscillator frequency of ad9361 over the range of 70Mhz to 6Ghz.

reference 

For this I am using the  spectrum_analyzer.c code as reference. I have also gone through UG570 and UG671.

Objective 

My ultimate objective is to sweep the frequency over this full wide range with the help of c code or in Verilog on ad9361. 

I need guidance to reach my objective. Despite going through the documents I have mentioned above, I am still not getting enough clarity on how to do it. Any kind of help would be appreciated! 

Thankx

Thread Notes

  • Please see here: https://wiki.analog.com/resources/tools-software/linux-drivers/iio-transceiver/ad9361#local_oscillator_control_lo

    Also page 23 here: https://www.gnuradio.org/grcon/grcon18/presentations/PlutoSDR/8-Michael_Hennerich.pdf

    I'm pretty sure you can't use Verilog to sweep over this range. 

    Controlling the RF PLL is a quite lookup and compute intensive task.

    -Michael

  • Hey  !

    1) If I understand the option as you pointed at page 23 then I have to write a C code for sweeping the RX LO? right?

    2)If I am correct then Kindly guide me if there is any helpful material available available on the forum

    2) Kindly you suggest  a suitable compiler for the code to run on the board.  

    Regards!

  • You need to update the: 

    out_altvoltage0_RX_LO_frequency, out_altvoltage1_TX_LO_frequency

    sysfs attrinutes, how you do that it doesn't matter. You can write a shell script,
    and write them directly. You can use iio_attr utility which can by the way generate example c code:

    https://wiki.analog.com/resources/tools-software/linux-software/libiio/iio_attr

    You can do things in python, etc.

    2) Kindly you suggest  a suitable compiler for the code to run on the board.

    You didn't mention which board...

    -Michael

  • Thanx  Its ad9361-z7035 . 

    You didn't mention which board..

    regards!

  • If you use our SD card image there is already a ARM GCC compiler installed.

  • hey  , As you suggested I have written the following code to sweep the LO frequency. 

    #include <unistd.h>
    #include <iio.h>
    #include <stdio.h>
    #include <stddef.h>

    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include <signal.h>
    #include <stdio.h>
    #include <errno.h>


    int main(void) {
    // Connect to IIO context
    struct iio_context *ctx = iio_create_local_context();
    if (!ctx) {
    perror("Unable to create IIO context");
    return -1;
    }

    // Open AD9361 device
    struct iio_device *dev = iio_context_find_device(ctx, "ad9361-phy");
    if (!dev) {
    perror("Unable to find AD9361 device");
    iio_context_destroy(ctx);
    return -1;
    }

    // Get the LO frequency attribute
    struct iio_channel *lo_channel = iio_device_find_channel(dev, "altvoltage0", true);
    if (!lo_channel) {
    perror("Unable to find LO frequency channel");
    iio_context_destroy(ctx);
    return -1;
    }

    // Define frequency range and step size
    // long start_frequency = 2400000000; // 2.4 GHz
    // long end_frequency = 2425000000; // 2.5 GHz
    // long step_frequency = 10000000; // GHz step
    long long s_frequency = 2400000000LL + (50000000.0/2.0);
    printf("Start frequency %lld Hz",s_frequency);
    long long e_frequency = 2500000000LL - (50000000.0/2.0);
    printf("Ending frequency %lld Hz", e_frequency);
    // Sweep frequencies
    for (s_frequency; s_frequency <= e_frequency; s_frequency += 10000000LL) {
    // printf("Setting LO frequency to %lld Hz\n", s_frequency);

    // Set LO frequency
    iio_channel_attr_write_longlong(lo_channel, "frequency", s_frequency);


    iio_context_destroy(ctx);
    return -1;
    }

    // Get the LO frequency attribute
    struct iio_channel *lo_channel = iio_device_find_channel(dev, "altvoltage0", true);
    if (!lo_channel) {
    perror("Unable to find LO frequency channel");
    iio_context_destroy(ctx);
    return -1;
    }

    // Define frequency range and step size
    // long start_frequency = 2400000000; // 2.4 GHz
    // long end_frequency = 2425000000; // 2.5 GHz
    // long step_frequency = 10000000; // GHz step
    long long s_frequency = 2400000000LL; // + (50000000.0/2.0);
    printf("Start frequency %lld Hz",s_frequency);
    long long e_frequency = 2500000000LL ; //- (50000000.0/2.0);
    printf("Ending frequency %lld Hz", e_frequency);
    // Sweep frequencies
    for (s_frequency; s_frequency <= e_frequency; s_frequency += 10000000LL) {
    // printf("Setting LO frequency to %lld Hz\n", s_frequency);

    // Set LO frequency
    iio_channel_attr_write_longlong(lo_channel, "frequency", s_frequency);
    printf("Setting LO frequency to %lld Hz\n", s_frequency );
    // Optionally, add a delay between frequency changes
    usleep(1000000); // 100ms delay
    }

    // Cleanup


    iio_channel_disable(lo_channel);

    iio_context_destroy(ctx);

    return 0;
    }

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

    it does sweeps the frequency, but the problem is when I check it on the iio- oscilloscope, there is a frequency mis-match. The frequencies that I I am controlling are different from the ones shown on the spectrum analyzer. You can easily compare the LO values in the left with the peak value in the right side. Though the cursor moves as I sweep the frequency, but the values are not synchronizing. Kindy guide me why it is happening and how can I fix it?

  • This doesn't surprise me.

    OSC fetches the currently LO frequency once it starts, and then later the plot is notified by a callback in case the LO or sampling frequency changes.

    https://github.com/analogdevicesinc/iio-oscilloscope/blob/master/plugins/fmcomms2.c#L317

    If you control things on the back of OSC using an external application, osc plot doesn't get notified.

  • Hey  ,I wanted to visualize the LO sweep on oscilloscope to authenticate it. What If I dont use oscillocope? Can you suggest me any other way to sweep the RX_LO which can assure me either RX LO is really sweeping or not?

  • Well, you can sweep the TX and observe it on a spectrum analyzer.

    Alternatively, use python to control and visualize.

    -Michael 

  • Hey  , I am sweeping the tx  from 400Mhz to 1100 Mhz. But I can only visualize the sweep on spectrum analyzer with the delay (sleep(1) ) of 1 second or greater. However, I want to lock the PLL as fast as possible. Moreover the default PLL lock time for ad9361 varries from 45 micro seconds to 60 micro seconds. Now tell me with this fast lock time how can I visualize it on the spectrum analyzer. 

    my spectrum analyzer (FSH8-2) allows to visualize as fast signals as that of 80ms.