NCO Fine Modulation Configuration using no-OS

Hi,

we are using ZYNQ zc706 + FMCDAQ2 board, the hdl branch we are also using is: hdl_2018_r2 with the no-OS master. We have generated our own signal using DMA instead of DDS at a certain frequency. The thing is: at this point our signal goes from 700KHz to 5MHz and we want to use Digital Modulation to use a carrier frequency of 52.5MHz. We saw in the datasheet that this can be done by seting the next: NCO Fine Modulation.

The carrier frequency is set by FTW in this manner:

we have configured this registers in the "ad9144_setup" function which is in the ad9144.c code as follows:

    //dac modulation mode set to NCO fine modulation
    ad9144_spi_write(dev, REG_DATAPATH_CTRL, 0b01);

    //frequency of the carrier
    ad9144_spi_write(dev, REG_FTW0, 0x20);
    ad9144_spi_write(dev, REG_FTW1, 0x16);
    ad9144_spi_write(dev, REG_FTW2, 0x21);
    ad9144_spi_write(dev, REG_FTW3, 0x03);
    ad9144_spi_write(dev, REG_FTW4, 0x00);
    ad9144_spi_write(dev, REG_FTW5, 0x00);

    //update & ack
    ad9144_spi_write(dev, REG_NCO_FTW_UPDATE, FTW_UPDATE_REQ);  
    ad9144_spi_write(dev, REG_NCO_FTW_UPDATE, FTW_UPDATE_ACK);

And this is not working. Can you help us with that issue? Can you indicate step by step the proper way to set up this digital modulation?

Thanks a lot!

Alex

Parents
  • 0
    •  Analog Employees 
    on Sep 22, 2020 1:53 PM 4 months ago

    Hi Alex,

    The FTW_UPDATE_ACK bit is read-only and will be high when the NCO is updated.I would try something like

    //frequency of the carrier
    ad9144_spi_write(dev, REG_FTW0, 0x20);
    ad9144_spi_write(dev, REG_FTW1, 0x16);
    ad9144_spi_write(dev, REG_FTW2, 0x21);
    ad9144_spi_write(dev, REG_FTW3, 0x03);
    ad9144_spi_write(dev, REG_FTW4, 0x00);
    ad9144_spi_write(dev, REG_FTW5, 0x00);
    
    //dac modulation mode set to NCO fine modulation
    ad9144_spi_write(dev, REG_DATAPATH_CTRL, 0b01);
    
    
    //update
    ad9144_spi_write(dev, REG_NCO_FTW_UPDATE, FTW_UPDATE_REQ);  
    
    //wait for ack
    uint8_t reg_val = 0;
    do {
    	ad9144_spi_read(dev, REG_NCO_FTW_UPDATE, &reg_val);
    } while(!(regval & FTW_UPDATE_ACK));

    Sergiu

  • Hello Segiu,

    we have tried your recommendation and we have noticed some issues:

    1) As you can see in the figure below (debugging the code), the FTW_UPDATE_ACK value is initialized to 2.

    This is done in the ad9144.h.  . We are able to change this FTW_UPDATE_ACK to 1, just inserting a (1<<0). By doing this the loop is not infinite anymore but the modulation is not taking any effect. So, we have the next questions:

    1) Is this manner correct?

    2) Is there anything else that we have to enable/change in some part of the code?

    3) can you help us with this issue?

    Best regards,

    Alex

  • We have noticed that we are using the unexpected no-OS code revision. We are using this fmcdaq2.c code:

    /***************************************************************************//**
     *   @file   ad_fmcdaq2_ebz.c
     *   @brief  Implementation of Main Function.
     *   @author DBogdan (dragos.bogdan@analog.com)
     *******************************************************************************
     * Copyright 2014-2016(c) Analog Devices, Inc.
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *  - Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *  - Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in
     *    the documentation and/or other materials provided with the
     *    distribution.
     *  - Neither the name of Analog Devices, Inc. nor the names of its
     *    contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *  - The use of this software may or may not infringe the patent rights
     *    of one or more patent holders.  This license does not release you
     *    from the requirement that you obtain separate licenses from these
     *    patent holders to use this software.
     *  - Use of the software either in source or binary form, must be run
     *    on or directly connected to an Analog Devices Inc. component.
     *
     * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
     * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
     * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     ******************************************************************************/
    
    /******************************************************************************/
    /***************************** Include Files **********************************/
    /******************************************************************************/
    
    #include "platform_drivers.h"
    #include "ad9144.h"
    #include "ad9523.h"
    #include "ad9680.h"
    #include "adc_core.h"
    #include "dac_core.h"
    #include "dmac_core.h"
    #include "dac_buffer.h"
    #include "xcvr_core.h"
    #include "jesd_core.h"
    
    /******************************************************************************/
    /********************** Macros and Constants Definitions **********************/
    /******************************************************************************/
    
    #define GPIO_TRIG		    43
    #define GPIO_ADC_PD		    42
    #define GPIO_DAC_TXEN		41
    #define GPIO_DAC_RESET		40
    #define GPIO_CLKD_SYNC		38
    #define GPIO_ADC_FDB		36
    #define GPIO_ADC_FDA		35
    #define GPIO_DAC_IRQ		34
    #define GPIO_CLKD_STATUS_1	33
    #define GPIO_CLKD_STATUS_0	32
    
    #define DDR_BASEADDR 		0x800000
    #define numberofsamples 	1024
    
    #define DMA_BUFFER		 1
    
    uint32_t rdata = 0; 
    uint32_t sampleI = 0; 
    uint32_t sampleQ = 0; 
    
    enum ad9523_channels {
    	DAC_DEVICE_CLK,
    	DAC_DEVICE_SYSREF,
    	DAC_FPGA_CLK,
    	DAC_FPGA_SYSREF,
    	ADC_DEVICE_CLK,
    	ADC_DEVICE_SYSREF,
    	ADC_FPGA_CLK,
    	ADC_FPGA_SYSREF,
    };
    
    /***************************************************************************//**
     * @brief main
     ******************************************************************************/
    int fmcdaq2_reconfig(struct ad9144_init_param *p_ad9144_param,
    		     xcvr_core *p_ad9144_xcvr,
    		     struct ad9680_init_param *p_ad9680_param,
    		     xcvr_core *p_ad9680_xcvr,
    		     struct ad9523_platform_data *p_ad9523_param)
    {
    
    	uint8_t mode = 0;
    
    	printf ("Available sampling rates:\n");
    	printf ("\t1 - ADC 1000 MSPS; DAC 1000 MSPS\n");
    	printf ("\t2 - ADC  500 MSPS; DAC 1000 MSPS\n");
    	printf ("\t3 - ADC  500 MSPS; DAC  500 MSPS\n");
    	printf ("\t4 - ADC  600 MSPS; DAC  600 MSPS\n");
    	printf ("\t5 - ADC 1000 MSPS; DAC 2000 MSPS (2x interpolation)\n");
    	printf ("choose an option [default 1]:\n");
    
    	mode = ad_uart_read();
    
    	switch (mode) {
    	case '5':
    		printf ("5 - ADC 1000 MSPS; DAC 2000 MSPS (2x interpolation)\n");
    		/* REF clock = 100 MHz */
    		p_ad9523_param->channels[DAC_DEVICE_CLK].channel_divider = 10;
    		p_ad9144_param->pll_ref_frequency_khz = 100000;
    
    		/* DAC at 2 GHz using the internal PLL and 2 times interpolation */
    		p_ad9144_param->interpolation = 2;
    		p_ad9144_param->pll_enable = 1;
    		p_ad9144_param->pll_dac_frequency_khz = 2000000;
    		break;
    	case '4':
    		printf ("4 - ADC  600 MSPS; DAC  600 MSPS\n");
    		p_ad9523_param->pll2_vco_diff_m1 = 5;
    		(&p_ad9523_param->channels[DAC_FPGA_CLK])->
    		channel_divider = 2;
    		(&p_ad9523_param->channels[DAC_DEVICE_CLK])->
    		channel_divider = 1;
    		(&p_ad9523_param->channels[DAC_DEVICE_SYSREF])->
    		channel_divider = 128;
    		(&p_ad9523_param->channels[DAC_FPGA_SYSREF])->
    		channel_divider = 128;
    		(&p_ad9523_param->channels[ADC_FPGA_CLK])->
    		channel_divider = 2;
    		(&p_ad9523_param->channels[ADC_DEVICE_CLK])->
    		channel_divider = 1;
    		(&p_ad9523_param->channels[ADC_DEVICE_SYSREF])->
    		channel_divider = 128;
    		(&p_ad9523_param->channels[ADC_FPGA_SYSREF])->
    		channel_divider = 128;
    		p_ad9144_xcvr->reconfig_bypass = 0;
    		p_ad9144_param->lane_rate_kbps = 6000000;
    		p_ad9144_xcvr->lane_rate_kbps = 6000000;
    		p_ad9144_xcvr->ref_rate_khz = 300000;
    		p_ad9680_xcvr->reconfig_bypass = 0;
    		p_ad9680_param->lane_rate_kbps = 6000000;
    		p_ad9680_xcvr->lane_rate_kbps = 6000000;
    		p_ad9680_xcvr->ref_rate_khz = 300000;
    #ifdef XILINX
    		p_ad9144_xcvr->dev.lpm_enable = 0;
    		p_ad9144_xcvr->dev.cpll_enable = 1;
    		p_ad9144_xcvr->dev.out_clk_sel = 4;
    
    		p_ad9680_xcvr->dev.lpm_enable = 1;
    		p_ad9680_xcvr->dev.cpll_enable = 1;
    		p_ad9680_xcvr->dev.out_clk_sel = 4;
    #endif
    		break;
    	case '3':
    		printf ("3 - ADC  500 MSPS; DAC  500 MSPS\n");
    		p_ad9523_param->pll2_vco_diff_m1 = 3;
    		(&p_ad9523_param->channels[DAC_FPGA_CLK])->
    		channel_divider = 4;
    		(&p_ad9523_param->channels[DAC_DEVICE_CLK])->
    		channel_divider = 2;
    		(&p_ad9523_param->channels[DAC_DEVICE_SYSREF])->
    		channel_divider = 256;
    		(&p_ad9523_param->channels[DAC_FPGA_SYSREF])->
    		channel_divider = 256;
    		(&p_ad9523_param->channels[ADC_FPGA_CLK])->
    		channel_divider = 4;
    		(&p_ad9523_param->channels[ADC_DEVICE_CLK])->
    		channel_divider = 2;
    		(&p_ad9523_param->channels[ADC_DEVICE_SYSREF])->
    		channel_divider = 256;
    		(&p_ad9523_param->channels[ADC_FPGA_SYSREF])->
    		channel_divider = 256;
    		p_ad9144_xcvr->reconfig_bypass = 0;
    		p_ad9144_param->lane_rate_kbps = 5000000;
    		p_ad9144_xcvr->lane_rate_kbps = 5000000;
    		p_ad9144_xcvr->ref_rate_khz = 250000;
    		p_ad9680_xcvr->reconfig_bypass = 0;
    		p_ad9680_param->lane_rate_kbps = 5000000;
    		p_ad9680_xcvr->lane_rate_kbps = 5000000;
    		p_ad9680_xcvr->ref_rate_khz = 250000;
    #ifdef XILINX
    		p_ad9144_xcvr->dev.lpm_enable = 1;
    		p_ad9144_xcvr->dev.cpll_enable = 1;
    		p_ad9144_xcvr->dev.out_clk_sel = 4;
    
    		p_ad9680_xcvr->dev.lpm_enable = 1;
    		p_ad9680_xcvr->dev.cpll_enable = 1;
    		p_ad9680_xcvr->dev.out_clk_sel = 4;
    #endif
    		break;
    	case '2':
    		printf ("2 - ADC  500 MSPS; DAC 1000 MSPS\n");
    		p_ad9523_param->pll2_vco_diff_m1 = 3;
    		(&p_ad9523_param->channels[DAC_FPGA_CLK])->
    		channel_divider = 2;
    		(&p_ad9523_param->channels[DAC_DEVICE_CLK])->
    		channel_divider = 1;
    		(&p_ad9523_param->channels[DAC_DEVICE_SYSREF])->
    		channel_divider = 128;
    		(&p_ad9523_param->channels[DAC_FPGA_SYSREF])->
    		channel_divider = 128;
    		(&p_ad9523_param->channels[ADC_FPGA_CLK])->
    		channel_divider = 4;
    		(&p_ad9523_param->channels[ADC_DEVICE_CLK])->
    		channel_divider = 2;
    		(&p_ad9523_param->channels[ADC_DEVICE_SYSREF])->
    		channel_divider = 256;
    		(&p_ad9523_param->channels[ADC_FPGA_SYSREF])->
    		channel_divider = 256;
    		p_ad9144_xcvr->reconfig_bypass = 0;
    		p_ad9144_param->lane_rate_kbps = 10000000;
    		p_ad9144_xcvr->lane_rate_kbps = 10000000;
    		p_ad9144_xcvr->ref_rate_khz = 500000;
    		p_ad9680_xcvr->reconfig_bypass = 0;
    		p_ad9680_param->lane_rate_kbps = 5000000;
    		p_ad9680_xcvr->lane_rate_kbps = 5000000;
    		p_ad9680_xcvr->ref_rate_khz = 250000;
    #ifdef XILINX
    		p_ad9144_xcvr->dev.lpm_enable = 0;
    		p_ad9144_xcvr->dev.cpll_enable = 0;
    		p_ad9144_xcvr->dev.out_clk_sel = 4;
    
    		p_ad9680_xcvr->dev.lpm_enable = 1;
    		p_ad9680_xcvr->dev.cpll_enable = 1;
    		p_ad9680_xcvr->dev.out_clk_sel = 4;
    #endif
    		break;
    	default:
    		printf ("1 - ADC 1000 MSPS; DAC 1000 MSPS\n");
    		p_ad9144_xcvr->ref_rate_khz = 500000;
    		p_ad9680_xcvr->ref_rate_khz = 500000;
    		break;
    	}
    
    	return(0);
    }
    
    /***************************************************************************//**
     * @brief main
     ******************************************************************************/
    int main(void)
    {
    	int n;
    
    	spi_init_param	ad9523_spi_param;
    	spi_init_param	ad9144_spi_param;
    	spi_init_param	ad9680_spi_param;
    
    #ifdef ALTERA
    	ad9523_spi_param.type = NIOS_II_SPI;
    	ad9144_spi_param.type = NIOS_II_SPI;
    	ad9680_spi_param.type = NIOS_II_SPI;
    #endif
    #ifdef ZYNQ_PS7
    	ad9523_spi_param.type = ZYNQ_PS7_SPI;
    	ad9144_spi_param.type = ZYNQ_PS7_SPI;
    	ad9680_spi_param.type = ZYNQ_PS7_SPI;
    #endif
    #ifdef ZYNQ_PSU
    	ad9523_spi_param.type = ZYNQ_PSU_SPI;
    	ad9144_spi_param.type = ZYNQ_PSU_SPI;
    	ad9680_spi_param.type = ZYNQ_PSU_SPI;
    #endif
    #ifdef MICROBLAZE
    	ad9523_spi_param.type = MICROBLAZE_SPI;
    	ad9144_spi_param.type = MICROBLAZE_SPI;
    	ad9680_spi_param.type = MICROBLAZE_SPI;
    #endif
    	ad9523_spi_param.chip_select = SPI_CHIP_SELECT(0);
    	ad9144_spi_param.chip_select = SPI_CHIP_SELECT(1);
    	ad9680_spi_param.chip_select = SPI_CHIP_SELECT(2);
    	ad9523_spi_param.cpha = 0;
    	ad9144_spi_param.cpha = 0;
    	ad9680_spi_param.cpha = 0;
    	ad9523_spi_param.cpol = 0;
    	ad9144_spi_param.cpol = 0;
    	ad9680_spi_param.cpol = 0;
    
    	struct ad9523_channel_spec	ad9523_channels[8];
    	struct ad9523_platform_data	ad9523_pdata;
    	struct ad9523_init_param	ad9523_param;
    	struct ad9144_init_param	ad9144_param;
    	struct ad9680_init_param	ad9680_param;
    
    	ad9523_param.spi_init = ad9523_spi_param;
    	ad9144_param.spi_init = ad9144_spi_param;
    	ad9680_param.spi_init = ad9680_spi_param;
    
    	struct ad9523_dev *ad9523_device;
    	struct ad9144_dev *ad9144_device;
    	struct ad9680_dev *ad9680_device;
    
    	dac_core		ad9144_core;
    	dac_channel		ad9144_channels[2];
    	jesd_core		ad9144_jesd;
    	dmac_core		ad9144_dma;
    	xcvr_core		ad9144_xcvr;
    	adc_core		ad9680_core;
    	jesd_core		ad9680_jesd;
    	xcvr_core		ad9680_xcvr;
    	dmac_core               ad9680_dma;
    	dmac_xfer               rx_xfer;
    	dmac_xfer               tx_xfer;
    
    //******************************************************************************
    // setup the base addresses
    //******************************************************************************
    
    #ifdef XILINX
    	ad9144_xcvr.base_address = XPAR_AXI_AD9144_XCVR_BASEADDR;
    	ad9144_core.base_address = XPAR_AXI_AD9144_CORE_BASEADDR;
    	ad9144_jesd.base_address = XPAR_AXI_AD9144_JESD_TX_AXI_BASEADDR;
    	ad9144_dma.base_address = XPAR_AXI_AD9144_DMA_BASEADDR;
    	ad9680_xcvr.base_address = XPAR_AXI_AD9680_XCVR_BASEADDR;
    	ad9680_core.base_address = XPAR_AXI_AD9680_CORE_BASEADDR;
    	ad9680_jesd.base_address = XPAR_AXI_AD9680_JESD_RX_AXI_BASEADDR;
    	ad9680_dma.base_address = XPAR_AXI_AD9680_DMA_BASEADDR;
    #endif
    
    #ifdef ZYNQ
    	rx_xfer.start_address = XPAR_DDR_MEM_BASEADDR + 0x800000;
    	tx_xfer.start_address = XPAR_DDR_MEM_BASEADDR + 0x900000;
    #endif
    
    #ifdef MICROBLAZE
    	rx_xfer.start_address = XPAR_AXI_DDR_CNTRL_BASEADDR + 0x800000;
    	tx_xfer.start_address = XPAR_AXI_DDR_CNTRL_BASEADDR + 0x900000;
    #endif
    
    #ifdef ALTERA
    	ad9144_xcvr.base_address =
    		AD9144_JESD204_LINK_MANAGEMENT_BASE;
    	ad9144_xcvr.dev.link_pll.base_address =
    		AD9144_JESD204_LINK_PLL_RECONFIG_BASE;
    	ad9144_xcvr.dev.atx_pll.base_address =
    		AD9144_JESD204_LANE_PLL_RECONFIG_BASE;
    	ad9144_core.base_address =
    		AXI_AD9144_CORE_BASE;
    	ad9680_xcvr.base_address =
    		AD9680_JESD204_LINK_MANAGEMENT_BASE;
    	ad9680_xcvr.dev.link_pll.base_address =
    		AD9680_JESD204_LINK_PLL_RECONFIG_BASE;
    	ad9680_core.base_address =
    		AXI_AD9680_CORE_BASE;
    	ad9144_jesd.base_address =
    		AD9144_JESD204_LINK_RECONFIG_BASE;
    	ad9680_jesd.base_address =
    		AD9680_JESD204_LINK_RECONFIG_BASE;
    
    	ad9144_xcvr.dev.channel_pll[0].type = cmu_tx_type;
    	ad9680_xcvr.dev.channel_pll[0].type = cmu_cdr_type;
    	ad9144_xcvr.dev.channel_pll[0].base_address = AVL_ADXCFG_0_RCFG_S0_BASE;
    	ad9680_xcvr.dev.channel_pll[0].base_address = AVL_ADXCFG_0_RCFG_S1_BASE;
    
    	ad9680_dma.base_address = AXI_AD9680_DMA_BASE;
    	ad9144_dma.base_address = AXI_AD9144_DMA_BASE;
    	rx_xfer.start_address =  0x800000;
    	tx_xfer.start_address =  0x900000;
    
    #endif
    
    //******************************************************************************
    // clock distribution device (AD9523) configuration
    //******************************************************************************
    
    	ad9523_pdata.num_channels = 8;
    	ad9523_pdata.channels = &ad9523_channels[0];
    	ad9523_param.pdata = &ad9523_pdata;
    	ad9523_init(&ad9523_param);
    
    	// dac device-clk-sysref, fpga-clk-sysref
    
    	ad9523_channels[DAC_DEVICE_CLK].channel_num = 1;
    	ad9523_channels[DAC_DEVICE_CLK].channel_divider = 1;
    	ad9523_channels[DAC_DEVICE_SYSREF].channel_num = 7;
    	ad9523_channels[DAC_DEVICE_SYSREF].channel_divider = 128;
    	ad9523_channels[DAC_FPGA_CLK].channel_num = 9;
    	ad9523_channels[DAC_FPGA_CLK].channel_divider = 2;
    	ad9523_channels[DAC_FPGA_SYSREF].channel_num = 8;
    	ad9523_channels[DAC_FPGA_SYSREF].channel_divider = 128;
    
    	// adc device-clk-sysref, fpga-clk-sysref
    
    	ad9523_channels[ADC_DEVICE_CLK].channel_num = 13;
    	ad9523_channels[ADC_DEVICE_CLK].channel_divider = 1;
    	ad9523_channels[ADC_DEVICE_SYSREF].channel_num = 6;
    	ad9523_channels[ADC_DEVICE_SYSREF].channel_divider = 128;
    	ad9523_channels[ADC_FPGA_CLK].channel_num = 4;
    	ad9523_channels[ADC_FPGA_CLK].channel_divider = 2;
    	ad9523_channels[ADC_FPGA_SYSREF].channel_num = 5;
    	ad9523_channels[ADC_FPGA_SYSREF].channel_divider = 128;
    
    	// VCXO 125MHz
    
    	ad9523_pdata.vcxo_freq = 125000000;
    	ad9523_pdata.spi3wire = 1;
    	ad9523_pdata.osc_in_diff_en = 1;
    	ad9523_pdata.pll2_charge_pump_current_nA = 413000;
    	ad9523_pdata.pll2_freq_doubler_en = 0;
    	ad9523_pdata.pll2_r2_div = 1;
    	ad9523_pdata.pll2_ndiv_a_cnt = 0;
    	ad9523_pdata.pll2_ndiv_b_cnt = 6;
    	ad9523_pdata.pll2_vco_diff_m1 = 3;
    	ad9523_pdata.pll2_vco_diff_m2 = 0;
    	ad9523_pdata.rpole2 = 0;
    	ad9523_pdata.rzero = 7;
    	ad9523_pdata.cpole1 = 2;
    
    	ad9144_xcvr.ref_rate_khz = 500000;
    	ad9680_xcvr.ref_rate_khz = 500000;
    
    //******************************************************************************
    // DAC (AD9144) and the transmit path (AXI_ADXCVR,
    //	JESD204, AXI_AD9144, TX DMAC) configuration
    //******************************************************************************
    
    	xcvr_getconfig(&ad9144_xcvr);
    	ad9144_xcvr.reconfig_bypass = 1;
    #ifdef XILINX
    	ad9144_xcvr.dev.cpll_enable = 0;
    #endif
    	ad9144_xcvr.lane_rate_kbps = 10000000;
    
    	ad9144_jesd.rx_tx_n = 0;
    	ad9144_jesd.scramble_enable = 1;
    	ad9144_jesd.octets_per_frame = 1;
    	ad9144_jesd.frames_per_multiframe = 32;
    	ad9144_jesd.subclass_mode = 1;
    
    	//THIS PARAMETERS ARE QUITE IMPORTANT IN ORDER TO UNDERSTAND THE GENERATION OF THE SINUS  
    
    	//******** CHANNEL 0 ********//
    	ad9144_channels[0].dds_dual_tone = 0;			   // if using single tone for this channel, set to 0x0
    	ad9144_channels[0].dds_frequency_0 = 100*1000*1000; // in hz (33*1000*1000 for MHz) -> yellow one in oscilloscope
    	ad9144_channels[0].dds_phase_0 = 0; 			   // in milli(?) angles (90*1000 for 90 degrees = pi/2)
    	ad9144_channels[0].dds_scale_0 = 500000;		   // in micro units (1.0*1000*1000 is 1.0)
    	ad9144_channels[0].pat_data = 0xb1b0a1a0;		   // if using SED/debug that sort of thing
    	ad9144_channels[0].sel = DAC_SRC_DMA;			   // set to one of the enumerated type above.
    
    	//******** CHANNEL 1 ********//
    	ad9144_channels[1].dds_dual_tone = 0;
    	ad9144_channels[1].dds_frequency_0 = 100*1000*1000; //ORIGINALLY 11MHz -> green one in the first report
    	ad9144_channels[1].dds_phase_0 = 0;
    	ad9144_channels[1].dds_scale_0 = 500000;
    	ad9144_channels[1].pat_data = 0xd1d0c1c0;	
    	ad9144_channels[1].sel = DAC_SRC_DMA;
    
    	ad9144_param.lane_rate_kbps = 10000000;
    	ad9144_param.spi3wire = 1;
    	ad9144_param.interpolation = 1;
    	ad9144_param.pll_enable = 0;
    	ad9144_param.jesd204_subclass = 1;
    	ad9144_param.jesd204_scrambling = 1;
    	ad9144_param.jesd204_mode = 4;
    	for(n=0; n<ARRAY_SIZE(ad9144_param.jesd204_lane_xbar); n++)
    		ad9144_param.jesd204_lane_xbar[n] = n;
    
    	ad9144_core.no_of_channels = 2;
    	ad9144_core.resolution = 16;
    	ad9144_core.channels = &ad9144_channels[0];
    
    	ad9144_param.stpl_samples[0][0] =
    		(ad9144_channels[0].pat_data >> 0)  & 0xffff;
    	ad9144_param.stpl_samples[0][1] =
    		(ad9144_channels[0].pat_data >> 16) & 0xffff;
    	ad9144_param.stpl_samples[0][2] =
    		(ad9144_channels[0].pat_data >> 0)  & 0xffff;
    	ad9144_param.stpl_samples[0][3] =
    		(ad9144_channels[0].pat_data >> 16) & 0xffff;
    	ad9144_param.stpl_samples[1][0] =
    		(ad9144_channels[1].pat_data >> 0)  & 0xffff;
    	ad9144_param.stpl_samples[1][1] =
    		(ad9144_channels[1].pat_data >> 16) & 0xffff;
    	ad9144_param.stpl_samples[1][2] =
    		(ad9144_channels[1].pat_data >> 0)  & 0xffff;
    	ad9144_param.stpl_samples[1][3] =
    		(ad9144_channels[1].pat_data >> 16) & 0xffff;
    
    //******************************************************************************
    // ADC (AD9680) and the receive path ( AXI_ADXCVR,
    //	JESD204, AXI_AD9680, TX DMAC) configuration
    //******************************************************************************
    
    	ad9680_param.lane_rate_kbps = 10000000;
    
    	xcvr_getconfig(&ad9680_xcvr);
    	ad9680_xcvr.reconfig_bypass = 1;
    #ifdef XILINX
    	ad9680_xcvr.dev.cpll_enable = 0;
    #endif
    	ad9680_xcvr.rx_tx_n = 1;
    	ad9680_xcvr.lane_rate_kbps = ad9680_param.lane_rate_kbps;
    
    	ad9680_jesd.scramble_enable = 1;
    	ad9680_jesd.octets_per_frame = 1;
    	ad9680_jesd.frames_per_multiframe = 32;
    	ad9680_jesd.subclass_mode = 1;
    
    	ad9680_core.no_of_channels = 2;
    	ad9680_core.resolution = 14;
    
    //******************************************************************************
    // configure the receiver DMA
    //******************************************************************************
    
    	ad9680_dma.type = DMAC_RX;
    	ad9680_dma.transfer = &rx_xfer;
    	rx_xfer.id = 0;
    	rx_xfer.no_of_samples = 32768;
    
    	ad9144_dma.type = DMAC_TX;
    	ad9144_dma.transfer = &tx_xfer;
    	ad9144_dma.flags = DMAC_FLAGS_TLAST;
    	tx_xfer.id = 0;
    	tx_xfer.no_of_samples = dac_buffer_load(ad9144_core, tx_xfer.start_address);
    
    //	mdelay(100);
    
    	// change the default JESD configurations, if required
    	fmcdaq2_reconfig(&ad9144_param,
    			 &ad9144_xcvr,
    			 &ad9680_param,
    			 &ad9680_xcvr,
    			 ad9523_param.pdata);
    
    //******************************************************************************
    // bring up the system
    //******************************************************************************
    
    	// setup GPIOs
    
    	gpio_desc *clkd_sync;
    	gpio_desc *dac_reset;
    	gpio_desc *dac_txen;
    	gpio_desc *adc_pd;
    
    	gpio_get(&clkd_sync, GPIO_CLKD_SYNC);
    	gpio_get(&dac_reset, GPIO_DAC_RESET);
    	gpio_get(&dac_txen,  GPIO_DAC_TXEN);
    	gpio_get(&adc_pd,    GPIO_ADC_PD);
    
    	gpio_set_value(clkd_sync, 0);
    	gpio_set_value(dac_reset, 0);
    	gpio_set_value(dac_txen,  0);
    	gpio_set_value(adc_pd,    1);
    	mdelay(5);
    
    	gpio_set_value(clkd_sync, 1);
    	gpio_set_value(dac_reset, 1);
    	gpio_set_value(dac_txen,  1);
    	gpio_set_value(adc_pd,    0);
    
    	// setup clocks
    
    	ad9523_setup(&ad9523_device, &ad9523_param);
    
    	// Recommended DAC JESD204 link startup sequence
    	//   1. FPGA JESD204 Link Layer
    	//   2. FPGA JESD204 PHY Layer
    	//   3. DAC
    	//
    	// Recommended ADC JESD204 link startup sequence
    	//   1. ADC
    	//   2. FPGA JESD204 PHY Layer
    	//   2. FPGA JESD204 Link Layer
    	//
    	// Both sequences are interleaved here so that the transceivers which might
    	// be shared between the DAC and ADC link are enabled at the same time.
    
    
    	// ADC
    	ad9680_setup(&ad9680_device, &ad9680_param);
    
    	// DAC FPGA JESD204 link layer
    	jesd_setup(&ad9144_jesd);
    
    	// ADC and DAC FPGA JESD204 PHY layer
    #ifdef ALTERA
    	xcvr_setup(&ad9144_xcvr);
    	xcvr_setup(&ad9680_xcvr);
    #endif
    #ifdef XILINX
    	if (!ad9144_xcvr.dev.cpll_enable) {	// DAC_XCVR controls the QPLL reset
    		xcvr_setup(&ad9144_xcvr);
    		xcvr_setup(&ad9680_xcvr);
    	} else {				// ADC_XCVR controls the CPLL reset
    		xcvr_setup(&ad9680_xcvr);
    		xcvr_setup(&ad9144_xcvr);
    	}
    #endif
    
    	// ADC FPGA JESD204 link layer
    	jesd_setup(&ad9680_jesd);
    
    	// DAC
    	ad9144_setup(&ad9144_device, &ad9144_param);
    
    	// JESD core status
    	axi_jesd204_tx_status_read(&ad9144_jesd);
    	axi_jesd204_rx_status_read(&ad9680_jesd);
    
    	// interface core set up
    	adc_setup(ad9680_core);
    	dac_setup(&ad9144_core);
    
    	ad9144_status(ad9144_device);
    
    //******************************************************************************
    // transport path testing
    //******************************************************************************
    
    	ad9144_channels[0].sel = DAC_SRC_SED;
    	ad9144_channels[1].sel = DAC_SRC_SED;
    	dac_data_setup(&ad9144_core);
    	ad9144_short_pattern_test(ad9144_device, &ad9144_param);
    
    	// PN7 data path test
    
    	ad9144_channels[0].sel = DAC_SRC_PN23;
    	ad9144_channels[1].sel = DAC_SRC_PN23;
    	dac_data_setup(&ad9144_core);
    	ad9144_param.prbs_type = AD9144_PRBS7;
    	ad9144_datapath_prbs_test(ad9144_device, &ad9144_param);
    
    	// PN15 data path test
    
    	ad9144_channels[0].sel = DAC_SRC_PN31;
    	ad9144_channels[1].sel = DAC_SRC_PN31;
    	dac_data_setup(&ad9144_core);
    	ad9144_param.prbs_type = AD9144_PRBS15;
    	ad9144_datapath_prbs_test(ad9144_device, &ad9144_param);
    
    //******************************************************************************
    // receive path testing
    //******************************************************************************
    
    	ad9680_test(ad9680_device, AD9680_TEST_PN9);
    	if(adc_pn_mon(ad9680_core, ADC_PN9) == -1) {
    		printf("%s ad9680 - PN9 sequence mismatch!\n", __func__);
    	};
    	ad9680_test(ad9680_device, AD9680_TEST_PN23);
    	if(adc_pn_mon(ad9680_core, ADC_PN23A) == -1) {
    		printf("%s ad9680 - PN23 sequence mismatch!\n", __func__);
    	};
    
    	// default data
    
    #if DMA_BUFFER
    	ad9144_channels[0].sel = DAC_SRC_DMA;
    	ad9144_channels[1].sel = DAC_SRC_DMA;
    	dac_data_setup(&ad9144_core);
    
    	if(!dmac_start_transaction(ad9144_dma)) {
    		printf("daq2: transmit data from memory\n");
    	};
    #else
    	ad9144_channels[0].sel = DAC_SRC_DDS;
    	ad9144_channels[1].sel = DAC_SRC_DDS;
    	dac_data_setup(&ad9144_core);
    
    	printf("daq2: setup and configuration is done\n");
    #endif
    //******************************************************************************
    // external loopback - capture data with DMA
    //******************************************************************************
    
    	ad9680_test(ad9680_device, AD9680_TEST_OFF);
    	if(!dmac_start_transaction(ad9680_dma)) {
    		printf("daq2: RX capture done.\n");
    	};
    
    	/* Memory deallocation for devices and spi */
    	ad9144_remove(ad9144_device);
    	ad9523_remove(ad9523_device);
    	ad9680_remove(ad9680_device);
    
    	/* Memory deallocation for gpios */
    	gpio_remove(clkd_sync);
    	gpio_remove(dac_reset);
    	gpio_remove(dac_txen);
    	gpio_remove(adc_pd);
    
    	/* For loop to capture data from ADC, we should clear memory inside this thing */
    	// adc_read(ad9680_core, DDR_BASEADDR);
    
    	// for(n=0; n<numberofsamples; n++)
    	// {
    	// 	rdata = Xil_In32(DDR_BASEADDR+(n*2)); 
    	// 	sampleI = rdata & 0xFFFF;
       	// 	sampleQ = (rdata >> 16) & 0xFFFF;
    	// 	xil_printf("%d, ",sampleI); 
    	// }
    	
    
    	return(0);
    }
    

    Should we move to the latest no-OS (fmcdaq2.c) revision?

    thanks

  • 0
    •  Analog Employees 
    on Sep 24, 2020 12:26 PM 3 months ago in reply to AlexGil

    Hi Alex,

    The fmcdaq2's hdl project got updated since hdl_2018_r2. I will run some tests on both branches and update the no-os driver if needed. Will come with a reply asap.

    Sergiu

  • 0
    •  Analog Employees 
    on Nov 13, 2020 5:43 PM 2 months ago in reply to Sergiu

    Hi ,

    I truly apologise for delaying you this much.

    There is a branch with some commits for the daq2 https://github.com/analogdevicesinc/no-OS/tree/fmcdaq2_update.

    You just have to add the following lines in no-OS/projects/fmcdaq2/src/app/app_config.h

    #define DAC_DMA_EXAMPLE
    #define USE_NCO

    The example sends an i-q sine defined in another file.

    If you want you can add your custom data you have to replace the sine_lut_iq array with yours.

    Also the ad9144_set_nco() function has the following parameters:

    1 - ad9144 device

    2- frequency in khz (in the example it is set at 62.5 MHZ and you get less aliases if the carrier frequency is F_dac_sampling_rate/4 or /8)

    3- phase in degrees

    Again, i apologise for the delay.

    Sergiu

  • Thanks a lot Sergiu,

    I am facing now with two problems:

    1) the link that you provide me is pointing to anywhere (not found error). I assume that the no-OS that you updated is the no-OS master branch. Can you confirm me that?

    2) With which HDL branch are you working? I am working with hdl_2018_r2 branch and I cannot build the no-OS master with that branch (I am using linux) and there appear the next error:

    [16:00:56] Evaluating hardware : system_top.hdf
    [16:01:00] Platform : xilinx
    [16:01:00] Building hardware specification and bsp
    [16:01:25] [CC] fmcdaq2.c
    In file included from /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/fmcdaq2.c:48:0:
    /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/fmcdaq2.c: In function 'fmcdaq2_dac_init':
    /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/parameters.h:79:28: error: 'XPAR_AXI_AD9144_TPL_DAC_TPL_CORE_BASEADDR' undeclared (first use in this function); did you mean 'XPAR_AXI_AD9144_JESD_TX_AXI_BASEADDR'?
     #define TX_CORE_BASEADDR   XPAR_AXI_AD9144_TPL_DAC_TPL_CORE_BASEADDR
                                ^
    /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/parameters.h:79:28: note: in definition of macro 'TX_CORE_BASEADDR'
     #define TX_CORE_BASEADDR   XPAR_AXI_AD9144_TPL_DAC_TPL_CORE_BASEADDR
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/parameters.h:79:28: note: each undeclared identifier is reported only once for each function it appears in
     #define TX_CORE_BASEADDR   XPAR_AXI_AD9144_TPL_DAC_TPL_CORE_BASEADDR
                                ^
    /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/parameters.h:79:28: note: in definition of macro 'TX_CORE_BASEADDR'
     #define TX_CORE_BASEADDR   XPAR_AXI_AD9144_TPL_DAC_TPL_CORE_BASEADDR
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/fmcdaq2.c: In function 'fmcdaq2_setup':
    /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/parameters.h:78:28: error: 'XPAR_AXI_AD9680_TPL_ADC_TPL_CORE_BASEADDR' undeclared (first use in this function); did you mean 'XPAR_AXI_AD9680_CORE_BASEADDR'?
     #define RX_CORE_BASEADDR   XPAR_AXI_AD9680_TPL_ADC_TPL_CORE_BASEADDR
                                ^
    /home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/build/app/src/parameters.h:78:28: note: in definition of macro 'RX_CORE_BASEADDR'
     #define RX_CORE_BASEADDR   XPAR_AXI_AD9680_TPL_ADC_TPL_CORE_BASEADDR
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/jesus/baseline_code_2019_master/no-OS-master/tools/scripts/linux.mk:262: recipe for target '/home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/src/app/fmcdaq2.o' failed
    make[2]: *** [/home/jesus/baseline_code_2019_master/no-OS-master/projects/fmcdaq2/src/app/fmcdaq2.o] Error 1
    /home/jesus/baseline_code_2019_master/no-OS-master/tools/scripts/linux.mk:299: recipe for target 'compile' failed
    make[1]: *** [compile] Error 2
    /home/jesus/baseline_code_2019_master/no-OS-master/tools/scripts/linux.mk:279: recipe for target 'all' failed
    make: *** [all] Error 2

    I think is because of the HDL branch. Can you point me to a branch that works with this no-OS?

    Thanks a lot again!

  • hello again Sergiu, 

    The other message is already fixed. I am using now: hdl master, no-OS master and Vivado 2019.1 and Linux on my PC and everything goes ok.

    Now I want to warn you that there is a bug or something wrong in the sw when uploading the app to the board. The issue is that the program stops when selecting the sampling rate, more in concrete in this part:

    And because of that the program is not running.

    Do you know why is this happening?

    Pd: I am using daq2 (hdl) and fmcdaq2 (no-OS) with zc706 board.

    Thnks!

  • +1
    •  Analog Employees 
    on Nov 24, 2020 12:09 PM 1 month ago in reply to AlexGil

    Hi Alex,

    If you are using the daq at 1GSPS you should change the vco max here:

    https://github.com/analogdevicesinc/no-OS/blob/master/drivers/axi_core/jesd204/xilinx_transceiver.c#L412

    from 3300000 to 5000000.

    After changing the value you should run make re in order to get the new sources.

    This is a workaround for getting the correct clock three for the jesd transceiver, until we find a better algorithm.

    Sergiu

  • Thanks a lot Sergiu for everything!

    Everything is working properly now.

    Thanks again, Alex

  • Dear Sergiu,

    just one more issue related to this branch. You explained to me that to add custom data I need to define DAC_DMA_EXAMPLE and also change the values of the sine_lut_iq which is into: axi_dac_core.c.

    The issue is that doing this changes, the output data is not changing and I would like to know if there are other changes from my side I need to do.

    Here I attach you the changes I made:

    After that, I build the project again in SDK and run it. But the signal is always the same at the output.

    Thanks, Alex

  • 0
    •  Analog Employees 
    on Nov 25, 2020 12:04 PM 1 month ago in reply to AlexGil

    Hi Alex,

    After rebuilding the project in the SDK, how do you run it? Using the SDK or the makefile from no-Os.

    If you're building the SDK, it will generate an .elf file, different from the one that's generated by our makefile (and probabli you're uploading the old file to the board).

    For SDK build use the builtin programming tool, for our makefile, edit the lut in /no-Os/drivers/axi_core/axi_dac_core/axi_dac_core.c (not the one in found in the build folder) save the cahges, run make re and make run.

    Sergiu

  • Hi Sergiu,

    I am tried with both SDK and makefile. Here I detail you a bit more what I am doing.

    1) Change 1GSPS. no-OS/drivers/axi_core/jesd204/xilinx_transceiver.c Change line 412 to 5000000.

    2) Change app_config.h: no-OS/projects/fmcdaq2/src/app/app_config.h (uncomment DAC_DMA_EXAMPLE)

    3) Change LUT: no-OS/drivers/axi_core/axi_dac_core/axi_dac_core.c (here I am just adding some zeros).

    then I do:

    make or make re if case of update. And after that make run to upload the .elf file to the board but still does not change the output of the board.

    Am I missing something?

    Alex

Reply
  • Hi Sergiu,

    I am tried with both SDK and makefile. Here I detail you a bit more what I am doing.

    1) Change 1GSPS. no-OS/drivers/axi_core/jesd204/xilinx_transceiver.c Change line 412 to 5000000.

    2) Change app_config.h: no-OS/projects/fmcdaq2/src/app/app_config.h (uncomment DAC_DMA_EXAMPLE)

    3) Change LUT: no-OS/drivers/axi_core/axi_dac_core/axi_dac_core.c (here I am just adding some zeros).

    then I do:

    make or make re if case of update. And after that make run to upload the .elf file to the board but still does not change the output of the board.

    Am I missing something?

    Alex

Children
No Data