Post Go back to editing

ad9361 received IQ samples missing

Category: Hardware

Hello everyone,

I am facing an issue with the AD9361 on the FMCOMMS3 using the no-os drivers. I am not able to receive correctly the IQ samples even though the interface timing validation passes.

I am using the timing validation method described here: https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/interface_timing_validation, so I am setting the parameter

init_param→digital_interface_tune_skip_mode (Init Parameter)
 to 0

The function passes, so i thought  everything was good. Then

I store a sinewave in the memory, and then i select it as a source for the DAC in this way:

    axi_dac_set_datasel(ad9361_phy->tx_dac, -1, AXI_DAC_DATA_SEL_DMA);
    axi_dac_set_sine_lut(ad9361_phy->tx_dac, DAC_DDR_BASEADDR);

Then I configure the AD9361 in loopback mode TX->RX:

ad9361_bist_loopback(ad9361_phy, 1);

and after that i capture the RX samples and store them inside the DDR. Then i take the samples out of the memory:

adc_sample = *(ADC_DDR_BASEADDR + index_mem);
I1 = (adc_sample >> 16) & 0xFFFF;
Q1 = adc_sample & 0xFFFF;

adc_sample = *(ADC_DDR_BASEADDR + index_mem+1);
I2 = (adc_sample >> 16) & 0xFFFF;
Q2 = adc_sample & 0xFFFF;

And i transfer them through UART on my PC. However what I get is the following:

What could be the issue?

However, when i use another platform to acquire RF data, I get a sinewave. Here in the figure below you can see the acquisition performed with PLUTO-SDR after configuring the FMCOMMS3 for transmission as explained above. So i guess that the transmitter interface is working correctly



added pluto capture
[edited by: ascialdo at 8:47 AM (GMT -5) on 2 Dec 2022]
  • Hi ,

    It seems that the data you are getting contains just a part of the sine wave. Have you tried to retrieve the data using the script in the following Wiki page?

    https://wiki.analog.com/resources/no-os/dac_dma_example

    Regards,

    George

  • Hello George, actually no because i am not on a xilinx FPGA, so I can't run the script.

    So i have a for loop that reads the memory location as i said before, and is sending each value through UART.

  • Hi ,

    Does the way in which you construct the data comply with the answer in the thread:  RE: when to use axi_dmac_transfer vs axi_dmac_transfer_nonblocking

    It seems that you receive some data, but the samples are not constructed or reconstructed correctly.

    Regards,

    George

  • Yes, It should be. In every memory location I have a 32 bits sample, which corresponds to one channel. The MSB are for the I component, while the LSB are for the Q component.

    So I read one memory location in this way

    adc_sample = *(ADC_DDR_BASEADDR + index_mem);

    and then i retrieve the I and Q component in this way


    I1 = (adc_sample >> 16) & 0xFFFF;
    Q1 = adc_sample & 0xFFFF;

    Is it not correct?

  • Hi ,

    Taking into consideration the discussion in the thread with the link in my previous comments, the data is interleaved, so, you would have:

    "x[i] = (i << 16) | i; //data for two channels, on 16 bits

    x[i+1] = x[i];

    In this case, the index should advance with two increments."

    i1 = (adc_sample >> 16) & 0xFFFF;

    i2 = adc_sample & 0xFFFF;

    q1 = ((adc_sample + 1) >> 16) & 0xFFFF;

    q2 = (adc_sample + 1) & 0xFFFF;

    Regards,

    George

  • So here is the entire piece of code I modified according to what you said, if i understood correctly:

            for (uint32_t index_mem = 0; index_mem < 1024; index_mem += 2) {
    
                axi_io_read(ADC_DDR_BASEADDR,index_mem*4,&adc_sample);
    
                I1 = (adc_sample >> 16) & 0xFFFF;
                I2 = (adc_sample) & 0xFFFF;
    
    
                axi_io_read(ADC_DDR_BASEADDR,(index_mem+1)*4,&adc_sample);
    
                Q1 = (adc_sample >> 16) & 0xFFFF;
                Q2 = adc_sample & 0xFFFF;
    
                uart_print(&I1, &g_uart);
                uart_print(&Q1, &g_uart);
    
                uart_print(&I2, &g_uart);
                uart_print(&Q2, &g_uart);
    
            }

    However, neither in this case i am able to retrieve the sinewave on my host-pc

  • Hi  ,

    I hope this helps. I have run the ad9361 project (current no-OS branch) with the following settings in app_config.h:

    #define ADC_DMA_EXAMPLE
    #define ADC_DMA_IRQ_EXAMPLE
    #define DAC_DMA_EXAMPLE

    The used hardware is ZC706+FMCOMMS5 (only one ad9361 is used).

    Loopback has been enabled:

    ad9361_bist_loopback(ad9361_phy, 1);

    I have just added the following piece of code after the completion of the DMA Rx transfer (the index advances with 4 positions since adc_buffer's elements are on 16-bits):

        for (uint32_t index_mem = 0; index_mem < 1024; index_mem += 4) {
        	printf("%d\n", adc_buffer[index_mem]);
        }

    The plot with the data is:

    Results

    Regards,

    George

  • Hi george,

    It just shows that the project is working as expected, but I knew it already since I also have a zedboard with the same project, but it doesn’t help for my current project that is based on another FPGA.

    I have another question then. could it be that the digital interface validation passes, but the receiver interface doesn’t work?

    Thanks a lot for your help anyway! 

  • Hi  ,

    Unfortunately, without knowing your setup it is hard to debug. What hardware are you using and which no-OS branch?

    If the validation passes, I would expect the receiver interface to work (the sample project for the ad9361 part also uses digital_interface_tune_skip_mode set to 0 and works correctly). Looking at the graph I would say that the interpretation needs more attention. Have you tried sending a simple ramp? This could help validate your receive component.

    Please, let us know about your progress.

    Regards,

    George

  • I am using the 2019_r2 branch, for both HDL and no-os.
    My setup is based on the FMCOMMS3 and the PolarFire FPGA. On the FPGA I have a soft-CPU that executes the code. 

    The validation passes, but there is a problem somewhere I can’t figure out. 

    I Am currently running the application in Debug mode through JTAG, so I can execute the code step by step. Using the debugger, I have looked inside the memory at the address where the RX DMA is supposed to store the samples, and I saw that I can’t find anywhere the values that I am sending, that is why I am thinking that the RX interface doesn’t work even though the validation passes. 
    I have no idea currently on what could be the problem, so if you have any idea please let me know. thanks!