AD9122 DDS phase

Hi,

I'm testing a custom board based on fmcomms 1 and ZED. my application is sfcw ranging. i have below questions........
the customization is instead of two adf4351, im using a single adf5355 to generate both tx and rx LOs.

1. Does the DDS start with the same phase every time i enable it ?
I'm running a python script to control the iio:devices and is there any way i can control the phase of the DDS ? 

2. if i use the DMA, will the data be repeatedly transmitted ?

3. So far i have tried 3 methods to write the data to tx buffer and failed.
    a. python to write /dev/iio:device4 (cf-ad9122-core-lpc)
    b. modified the ad9361-iiostream.c file to push the tx data buffer
    c. used iio oscilloscope to load data to buffer

any insight in to the above issues will be helpful. thanks 

 

Regards,

Anojh

Top Replies

Parents
  • 0
    •  Analog Employees 
    on Sep 8, 2020 3:11 PM 4 months ago

    Hi Anojh,What version(git branch) of HDL are you using? I recently made some changes to the DDS on the master branch.

    1. Does the DDS start with the same phase every time i enable it ?

    Yes.
    https://github.com/analogdevicesinc/hdl/blob/hdl_2016_r1/library/axi_ad9122/axi_ad9122_channel.v#L158

    I'm running a python script to control the iio:devices and is there any way i can control the phase of the DDS ? 

    You should be able to access the dac registers through IIO, so yes. Click on the channel link(click to expand) from the regmap section https://wiki.analog.com/resources/fpga/docs/axi_dac_ip#register_map.

    Take a look at the registers that contain the word DDS.


    2. if i use the DMA, will the data be repeatedly transmitted ?

    The DMA does have the cyclic feature enabled. So, if you configure the for a cyclic buffer than yes.
    https://github.com/analogdevicesinc/hdl/blob/hdl_2016_r1/projects/fmcomms1/common/fmcomms1_bd.tcl#L35

    3. So far i have tried 3 methods to write the data to tx buffer and failed.
        a. python to write /dev/iio:device4 (cf-ad9122-core-lpc)
        b. modified the ad9361-iiostream.c file to push the tx data buffer
        c. used iio oscilloscope to load data to buffer

    I think  can help you with this one, but again, what git branches are you using, for all of the repos you are working with?
    The example I posted are from hdl_2016_r1 release. The last release in which the fmcomms1 project was supported.Andrei

  • Hi Andrei,

    Thanks for the info. i will check and get back if i need further info on the first 2 questions 

    for the 3rd question, I'm actually using the 2016_R1-2016_12_23.img. I believe that since i'm already running the latest image, there is no use in running the update scripts ?

    on the AD9122, when i run the shell script which passes random data to DMA, it's indefinitely stuck at the dd command. to make the dd work, i had to enable the scan elements first , then enable the tx buffer and then write the data to buffer (but according to the documentation, buffer has to be enabled last). but yet im unable to see the correct output at the output of DAC so i'm bit confused.

    on the AD9463, right now i'm using plain python (attached an ex .py file) to read and write to the file system (/sys/bus/iio/devices/iio:devicex) to control the devices. i'm not sure if reading the ADC rx buffer (/dev/iio:device5) as a file will work ? and i'm also wondering if the libiio python bindings will work for this version of linux image ?
     
    any help will be appreciated. thanks

    import time
    import serial
    import os
    
    # Initialize board parameters
    
    # buffer size, let's use 512 samples, or 1024 bytes
    tx_buffer_size=1024
    rx_buffer_size=1024
    
    # fmcw parameters
    baseband_freq_I=40 #MHz
    baseband_freq_Q=40 #MHz
    baseband_amp=1.0/pow(2,3)
    start_freq=1000 #MHz
    end_freq=6000 #MHz
    step_freq=100 #MHz
    steps = (end_freq - start_freq)/step_freq
    pause=1 #sec
    duty_cycle=1 #sec
    vga_gain=10 #dB
    
    #device paths
    common_path='/sys/bus/iio/devices'
    adc_path=common_path+'/iio:device5'
    #adc_path='/sys/devices/soc0/fpga-axi@0/79020000.cf-ad9643-core-lpc/iio:device5'
    adc_dev='/dev/iio:device5'
    #dac_path='/sys/devices/soc0/fpga-axi@0/74204000.cf-ad9122-core-lpc/iio:device4'
    dac_path=common_path+'/iio:device4'
    dac_dev='/dev/iio:device4'
    #lo_path='/sys/devices/soc0/fpga-axi@0/41620000.i2c/i2c-1/1-0058/spi_master/spi32765/spi32765.5/iio:device3'
    lo_path=common_path+'/iio:device3'
    lo_dev='/dev/iio:device3'
    #clk_path='/sys/devices/soc0/fpga-axi@0/41620000.i2c/i2c-1/1-0058/spi_master/spi32765/spi32765.3/iio:device2'
    clk_path=common_path+'/iio:device2'
    clk_dev='/dev/iio:device2'
    #vga_path='/sys/devices/soc0/fpga-axi@0/41620000.i2c/i2c-1/1-0058/spi_master/spi32765/spi32765.6/iio:device1'
    vga_path=common_path+'/iio:device1'
    vga_dev='/dev/iio:device1'
    
    #find all devices
    #find all devices
    #serial port
    ser = serial.Serial( port='/dev/ttyPS0', baudrate=115200)
    if ser.isOpen():
        ser.close()
    ser.open()
    ser.isOpen()
    #save the current dac settings
    
    #file operation
    def readFile(path):
        f = open(path, 'r')
        return f.read()
        
    def writeFile(path, data):
        f = open(path, 'w')
        f.write(str(data)+'\n')
        return 0
    
    # Set DDS func
    def set_dac_freq(freqA, freqB):
        writeFile(dac_path+'/out_altvoltage0_1A_frequency', freqA)
        writeFile(dac_path+'/out_altvoltage2_2A_frequency', freqA)
        print 'dac set I:'+readFile(dac_path+'/out_altvoltage2_2A_frequency')
        
        writeFile(dac_path+'/out_altvoltage1_1B_frequency', freqB)
        writeFile(dac_path+'/out_altvoltage3_2B_frequency', freqB)
        print 'dac set Q:'+readFile(dac_path+'/out_altvoltage3_2B_frequency')
    
    # Set DDS phase
    def set_dac_phase(phaseA, phaseB):
        writeFile(dac_path+'/out_altvoltage0_1A_phase', phaseA)
        writeFile(dac_path+'/out_altvoltage1_1B_phase', phaseA)
        print 'dac set I phase:'+readFile(dac_path+'/out_altvoltage2_2A_phase')
        
        writeFile(dac_path+'/out_altvoltage2_2A_phase', phaseB)
        writeFile(dac_path+'/out_altvoltage3_2B_phase', phaseB)
        print 'dac set Q phase:'+readFile(dac_path+'/out_altvoltage3_2B_phase')
    
    # Set LO func
    def set_lo_freq(freq):
        writeFile(lo_path+'/out_altvoltage0_frequency', freq)
        print 'lo freq:'+readFile(lo_path+'/out_altvoltage0_frequency')
    
    # enable/disable DDS
    def enableDDS(en):
        writeFile(dac_path+'/out_altvoltage0_1A_raw', en)
        writeFile(dac_path+'/out_altvoltage1_1B_raw', en)
        writeFile(dac_path+'/out_altvoltage2_2A_raw', en)
        writeFile(dac_path+'/out_altvoltage3_2B_raw', en)
        
    #power down LO
    writeFile(lo_path+'/out_altvoltage0_powerdown', 1)
    writeFile(lo_path+'/out_altvoltage1_powerdown', 1)
    print 'lo pwrdwn:'+readFile(lo_path+'/out_altvoltage1_powerdown')
    
    # set the buffer sizes
    writeFile(dac_path+'/buffer/length', tx_buffer_size)
    writeFile(adc_path+'/buffer/length', rx_buffer_size)
    print 'dac buff:'+readFile(adc_path+'/buffer/length')
    
    # Set Gain
    writeFile(vga_path+'/out_voltage0_hardwaregain', vga_gain)
    writeFile(vga_path+'/out_voltage1_hardwaregain', vga_gain)
    print 'vga gain:'+readFile(vga_path+'/out_voltage1_hardwaregain')
    
    #set baseband amplitude
    writeFile(dac_path+'/out_altvoltage0_1A_scale', baseband_amp )
    writeFile(dac_path+'/out_altvoltage1_1B_scale', baseband_amp )
    writeFile(dac_path+'/out_altvoltage2_2A_scale', baseband_amp )
    writeFile(dac_path+'/out_altvoltage3_2B_scale', baseband_amp )
    print 'dac amplitude:'+readFile(dac_path+'/out_altvoltage3_2B_scale')
    
    #set dds freq
    set_dac_freq(baseband_freq_I*1000000, baseband_freq_Q*1000000)
    print "I : " +repr(baseband_freq_I)+ "MHz"
    print "Q : " +repr(baseband_freq_I)+ "MHz"
    
    #disable DDS
    enableDDS(0)
    
    #for freq in [1000]: 
    for freq in range(start_freq, end_freq, step_freq):
    
    	#enable buffer
            #writeFile(adc_path+'/buffer/enable', 1)
        
    	#set dds freq
    	#set_dac_freq(0, 0)
    
    	#time.sleep(0.001)
    	
    	#set lo freq
    	set_lo_freq(freq*1000000)
    	print "LO: " +repr(freq)+ "MHz"
    	
    	#power up LO channel A
    	writeFile(lo_path+'/out_altvoltage0_powerdown', 0)
    	print 'lo pwrdwn:'+readFile(lo_path+'/out_altvoltage0_powerdown')
    
        	#time.sleep(1)    
    
    	#enable buffer
    	writeFile(adc_path+'/buffer/enable', 1)
    
    	#enable dds
    	enableDDS(1)
    
       	time.sleep(2)
        	#copy data file
        	#os.popen('cp data_path /root/data/data.txt')
        	#f = open(adc_dev, 'r')
        	#content=f.read(rx_buffer_size)
        	#hex_list = ["{:02x}".format(ord(c)) for c in content]
    
        	#print repr(hex_list)
        	#print(int(hex_list,16))
    
        	#Isamples=list()
        	#Qsamples=list()
    
        	#for i in range(0,len(hex_list)-3,4):
            #	Isamples.append(int(hex_list[i],16))
            #	Isamples.append(int(hex_list[i+1],16))
            #	Qsamples.append(int(hex_list[i+2],16))
            #	Qsamples.append(int(hex_list[i+3],16))
    
        	#print('\n')
        	#print repr(Isamples)
        	#print('\n')
        	#print(Qsamples)
    
        	#write to serial port
        	#ser.write(Isamples)
        	#ser.write(Qsamples)
    
        	#disable buffer
        	#writeFile(adc_path+'/buffer/enable', 0)
    
    	enableDDS(0)
        
    	#power down  LO channel A
            writeFile(lo_path+'/out_altvoltage0_powerdown', 1)
            print 'lo pwrdwn:'+readFile(lo_path+'/out_altvoltage0_powerdown')
    	
        	#f.close()
       
        	time.sleep(0.1)
    
    ser.close()
    

Reply
  • Hi Andrei,

    Thanks for the info. i will check and get back if i need further info on the first 2 questions 

    for the 3rd question, I'm actually using the 2016_R1-2016_12_23.img. I believe that since i'm already running the latest image, there is no use in running the update scripts ?

    on the AD9122, when i run the shell script which passes random data to DMA, it's indefinitely stuck at the dd command. to make the dd work, i had to enable the scan elements first , then enable the tx buffer and then write the data to buffer (but according to the documentation, buffer has to be enabled last). but yet im unable to see the correct output at the output of DAC so i'm bit confused.

    on the AD9463, right now i'm using plain python (attached an ex .py file) to read and write to the file system (/sys/bus/iio/devices/iio:devicex) to control the devices. i'm not sure if reading the ADC rx buffer (/dev/iio:device5) as a file will work ? and i'm also wondering if the libiio python bindings will work for this version of linux image ?
     
    any help will be appreciated. thanks

    import time
    import serial
    import os
    
    # Initialize board parameters
    
    # buffer size, let's use 512 samples, or 1024 bytes
    tx_buffer_size=1024
    rx_buffer_size=1024
    
    # fmcw parameters
    baseband_freq_I=40 #MHz
    baseband_freq_Q=40 #MHz
    baseband_amp=1.0/pow(2,3)
    start_freq=1000 #MHz
    end_freq=6000 #MHz
    step_freq=100 #MHz
    steps = (end_freq - start_freq)/step_freq
    pause=1 #sec
    duty_cycle=1 #sec
    vga_gain=10 #dB
    
    #device paths
    common_path='/sys/bus/iio/devices'
    adc_path=common_path+'/iio:device5'
    #adc_path='/sys/devices/soc0/fpga-axi@0/79020000.cf-ad9643-core-lpc/iio:device5'
    adc_dev='/dev/iio:device5'
    #dac_path='/sys/devices/soc0/fpga-axi@0/74204000.cf-ad9122-core-lpc/iio:device4'
    dac_path=common_path+'/iio:device4'
    dac_dev='/dev/iio:device4'
    #lo_path='/sys/devices/soc0/fpga-axi@0/41620000.i2c/i2c-1/1-0058/spi_master/spi32765/spi32765.5/iio:device3'
    lo_path=common_path+'/iio:device3'
    lo_dev='/dev/iio:device3'
    #clk_path='/sys/devices/soc0/fpga-axi@0/41620000.i2c/i2c-1/1-0058/spi_master/spi32765/spi32765.3/iio:device2'
    clk_path=common_path+'/iio:device2'
    clk_dev='/dev/iio:device2'
    #vga_path='/sys/devices/soc0/fpga-axi@0/41620000.i2c/i2c-1/1-0058/spi_master/spi32765/spi32765.6/iio:device1'
    vga_path=common_path+'/iio:device1'
    vga_dev='/dev/iio:device1'
    
    #find all devices
    #find all devices
    #serial port
    ser = serial.Serial( port='/dev/ttyPS0', baudrate=115200)
    if ser.isOpen():
        ser.close()
    ser.open()
    ser.isOpen()
    #save the current dac settings
    
    #file operation
    def readFile(path):
        f = open(path, 'r')
        return f.read()
        
    def writeFile(path, data):
        f = open(path, 'w')
        f.write(str(data)+'\n')
        return 0
    
    # Set DDS func
    def set_dac_freq(freqA, freqB):
        writeFile(dac_path+'/out_altvoltage0_1A_frequency', freqA)
        writeFile(dac_path+'/out_altvoltage2_2A_frequency', freqA)
        print 'dac set I:'+readFile(dac_path+'/out_altvoltage2_2A_frequency')
        
        writeFile(dac_path+'/out_altvoltage1_1B_frequency', freqB)
        writeFile(dac_path+'/out_altvoltage3_2B_frequency', freqB)
        print 'dac set Q:'+readFile(dac_path+'/out_altvoltage3_2B_frequency')
    
    # Set DDS phase
    def set_dac_phase(phaseA, phaseB):
        writeFile(dac_path+'/out_altvoltage0_1A_phase', phaseA)
        writeFile(dac_path+'/out_altvoltage1_1B_phase', phaseA)
        print 'dac set I phase:'+readFile(dac_path+'/out_altvoltage2_2A_phase')
        
        writeFile(dac_path+'/out_altvoltage2_2A_phase', phaseB)
        writeFile(dac_path+'/out_altvoltage3_2B_phase', phaseB)
        print 'dac set Q phase:'+readFile(dac_path+'/out_altvoltage3_2B_phase')
    
    # Set LO func
    def set_lo_freq(freq):
        writeFile(lo_path+'/out_altvoltage0_frequency', freq)
        print 'lo freq:'+readFile(lo_path+'/out_altvoltage0_frequency')
    
    # enable/disable DDS
    def enableDDS(en):
        writeFile(dac_path+'/out_altvoltage0_1A_raw', en)
        writeFile(dac_path+'/out_altvoltage1_1B_raw', en)
        writeFile(dac_path+'/out_altvoltage2_2A_raw', en)
        writeFile(dac_path+'/out_altvoltage3_2B_raw', en)
        
    #power down LO
    writeFile(lo_path+'/out_altvoltage0_powerdown', 1)
    writeFile(lo_path+'/out_altvoltage1_powerdown', 1)
    print 'lo pwrdwn:'+readFile(lo_path+'/out_altvoltage1_powerdown')
    
    # set the buffer sizes
    writeFile(dac_path+'/buffer/length', tx_buffer_size)
    writeFile(adc_path+'/buffer/length', rx_buffer_size)
    print 'dac buff:'+readFile(adc_path+'/buffer/length')
    
    # Set Gain
    writeFile(vga_path+'/out_voltage0_hardwaregain', vga_gain)
    writeFile(vga_path+'/out_voltage1_hardwaregain', vga_gain)
    print 'vga gain:'+readFile(vga_path+'/out_voltage1_hardwaregain')
    
    #set baseband amplitude
    writeFile(dac_path+'/out_altvoltage0_1A_scale', baseband_amp )
    writeFile(dac_path+'/out_altvoltage1_1B_scale', baseband_amp )
    writeFile(dac_path+'/out_altvoltage2_2A_scale', baseband_amp )
    writeFile(dac_path+'/out_altvoltage3_2B_scale', baseband_amp )
    print 'dac amplitude:'+readFile(dac_path+'/out_altvoltage3_2B_scale')
    
    #set dds freq
    set_dac_freq(baseband_freq_I*1000000, baseband_freq_Q*1000000)
    print "I : " +repr(baseband_freq_I)+ "MHz"
    print "Q : " +repr(baseband_freq_I)+ "MHz"
    
    #disable DDS
    enableDDS(0)
    
    #for freq in [1000]: 
    for freq in range(start_freq, end_freq, step_freq):
    
    	#enable buffer
            #writeFile(adc_path+'/buffer/enable', 1)
        
    	#set dds freq
    	#set_dac_freq(0, 0)
    
    	#time.sleep(0.001)
    	
    	#set lo freq
    	set_lo_freq(freq*1000000)
    	print "LO: " +repr(freq)+ "MHz"
    	
    	#power up LO channel A
    	writeFile(lo_path+'/out_altvoltage0_powerdown', 0)
    	print 'lo pwrdwn:'+readFile(lo_path+'/out_altvoltage0_powerdown')
    
        	#time.sleep(1)    
    
    	#enable buffer
    	writeFile(adc_path+'/buffer/enable', 1)
    
    	#enable dds
    	enableDDS(1)
    
       	time.sleep(2)
        	#copy data file
        	#os.popen('cp data_path /root/data/data.txt')
        	#f = open(adc_dev, 'r')
        	#content=f.read(rx_buffer_size)
        	#hex_list = ["{:02x}".format(ord(c)) for c in content]
    
        	#print repr(hex_list)
        	#print(int(hex_list,16))
    
        	#Isamples=list()
        	#Qsamples=list()
    
        	#for i in range(0,len(hex_list)-3,4):
            #	Isamples.append(int(hex_list[i],16))
            #	Isamples.append(int(hex_list[i+1],16))
            #	Qsamples.append(int(hex_list[i+2],16))
            #	Qsamples.append(int(hex_list[i+3],16))
    
        	#print('\n')
        	#print repr(Isamples)
        	#print('\n')
        	#print(Qsamples)
    
        	#write to serial port
        	#ser.write(Isamples)
        	#ser.write(Qsamples)
    
        	#disable buffer
        	#writeFile(adc_path+'/buffer/enable', 0)
    
    	enableDDS(0)
        
    	#power down  LO channel A
            writeFile(lo_path+'/out_altvoltage0_powerdown', 1)
            print 'lo pwrdwn:'+readFile(lo_path+'/out_altvoltage0_powerdown')
    	
        	#f.close()
       
        	time.sleep(0.1)
    
    ser.close()
    

Children