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
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…
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, ®_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,
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
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.
Hi AlexGil,
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.
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' failedmake[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' failedmake[1]: *** [compile] Error 2/home/jesus/baseline_code_2019_master/no-OS-master/tools/scripts/linux.mk:279: recipe for target 'all' failedmake: *** [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!
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.
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
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.
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?