For our project we need to clock this dac with an external 2.6 to 3 GHz clock. We want to do this on the evaluation board without any kind of modification to avoid damage risk.
This removes the option of using direct clock to the dac from J31. Following schematic and and datasheet of HMC7044, we figured out that we can use J41 as a clock input, as it feeds the external VCO input on the PLL2 VCO MUX, and the input frequency range satisfies our needs. The board driving the DAC is ZCU102, on which we are using the reference design on your repository (version hdl_2021_R1) using JESD mode 20, plus no-os driver and reference main.c also provided in the repository.
Below is the way we are configuring the structures the way we think it needs to be done for our purpose.
uint32_t hmc_freq_hz = 2600*1000*1000; uint32_t dac_freq_khz = 5200*1000; uint32_t hmc_divisor = 4; uint32_t ref_rate_khz = (hmc_freq_hz/1000)/hmc_divisor; //Lane rate = (M × N' × [10⁄8] × Fs) ∕ L = (1*16*1.25*dac_freq_khz)/8 uint32_t lane_clk_khz = dac_freq_khz*2.5; uint32_t device_clk_khz = lane_clk_khz/40; struct xil_spi_init_param xil_spi_param = { .type = SPI_PS, .flags = 0 }; struct no_os_spi_init_param hmc7044_spi_param = { .device_id = SPI_DEVICE_ID, .max_speed_hz = 10000000, .mode = NO_OS_SPI_MODE_0, .chip_select = SPI_HMC7044_CS, .platform_ops = &xil_spi_ops, .extra = &xil_spi_param }; struct hmc7044_chan_spec chan_spec[4] = { {.disable = 0, .num = 2, .divider = hmc_divisor, .driver_mode = 1}, /* DAC_CLK */ {.disable = 0, .num = 3, .divider = 512, .driver_mode = 1}, /* DAC_SYSREF */ {.disable = 0, .num = 12, .divider = hmc_divisor, .driver_mode = 2}, /* FPGA_CLK */ {.disable = 0, .num = 13, .divider = 512, .driver_mode = 2}, /* FPGA_SYSREF */ }; struct hmc7044_init_param hmc7044_param = { .spi_init = &hmc7044_spi_param, .clkin_freq = {0, 2600000000, 0, 0}, .vcxo_freq = 0, .pll2_freq = hmc_freq_hz, .pll1_loop_bw = 200, .sysref_timer_div = 1024, .clkin0_rfsync_en = false, .clkin1_vcoin_en = true, .pulse_gen_mode = 0, .in_buf_mode = {0, 0x5, 0, 0, 0}, .gpi_ctrl = {0x00, 0x00, 0x00, 0x00}, .gpo_ctrl = {0x1f, 0x2b, 0x00, 0x00}, .num_channels = 4, .channels = chan_spec, }; struct jesd204_tx_init tx_jesd_init = { .name = "tx_jesd", .base = TX_JESD_BASEADDR, .octets_per_frame = 1,//original value => 2 .frames_per_multiframe = 32, .converters_per_device = 1,//original value => 4 .converter_resolution = 16, .bits_per_sample = 16, .high_density = true,//original value => false .control_bits_per_sample = 0, .subclass = 1, .device_clk_khz = device_clk_khz, /* (lane_clk_khz / 40) */ .lane_clk_khz = lane_clk_khz, /* LaneRate = ( M/L)*NP*(10/8)*DataRate */ }; struct adxcvr_init tx_adxcvr_init = { .name = "tx_adxcvr", .base = TX_XCVR_BASEADDR, .sys_clk_sel = 3, .out_clk_sel = 4, .lpm_enable = 1, .lane_rate_khz = lane_clk_khz, /* LaneRate = ( M/L)*NP*(10/8)*DataRate */ .ref_rate_khz = ref_rate_khz, /* FPGA_CLK, output 12 of HMC 7044 mult. 32 o 40*/ }; struct no_os_spi_init_param ad9172_spi_param = { .max_speed_hz = 1000000, .mode = NO_OS_SPI_MODE_0, .chip_select = SPI_AD9172_CS, .platform_ops = &xil_spi_ops, .extra = &xil_spi_param }; struct xil_gpio_init_param xilinx_gpio_init_param = { .type = GPIO_PS, .device_id = GPIO_DEVICE_ID }; struct ad9172_init_param ad9172_param = { .spi_init = &ad9172_spi_param, /* no_os_spi_init_param */ .gpio_reset = { .number = 54 + 0, .platform_ops = &xil_gpio_ops, .extra = &xilinx_gpio_init_param }, .gpio_txen0 = { .number = 54 + 22, .platform_ops = &xil_gpio_ops, .extra = &xilinx_gpio_init_param }, .gpio_txen1 = { .number = 54 + 23, .platform_ops = &xil_gpio_ops, .extra = &xilinx_gpio_init_param }, .dac_rate_khz = dac_freq_khz, /* or sample rate */ .dac_clkin_Hz = ref_rate_khz*1000, /* DAC_CLK, output 2 of HMC 7044 */ .jesd_link_mode = 20, .jesd_subclass = 1, .dac_interpolation = 1, .channel_interpolation = 1, .clock_output_config = 4, .syncoutb_type = SIGNAL_LVDS, .sysref_coupling = COUPLING_AC, }; struct axi_dac_init tx_dac_init = { "tx_dac", TX_CORE_BASEADDR, 8, NULL };
Additionally, we modified the driver (hmc7044.c file, line 533), as there are some register options that can't be accessed through the structures (Reg 0x0003 to use external VCO).
/* Select the VCO range */ hmc7044_write(dev, HMC7044_REG_EN_CTRL_0, (dev->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) | HMC7044_VCO_SEL(HMC7044_VCO_EXT/*high_vco_en ? HMC7044_VCO_HIGH : HMC7044_VCO_LOW*/) | HMC7044_SYSREF_TIMER_EN | 0/*HMC7044_PLL2_EN*/ | 0/*HMC7044_PLL1_EN*/);
What the fpga spits out back to us is this:
tx_adxcvr: OK (13000000 kHz) AD917x DAC Chip ID: 4 AD917x DAC Product ID: 9176 AD917x DAC Product Grade: 0 AD917x DAC Product Revision: 7 AD917x Revision: 1.1.1 PLL Input rate 650000000 PLL lock status 0, DLL lock status: 1 Serdes PLL Locked (stat: 3) code_grp_sync: 0 frame_sync_stat: 0 good_checksum_stat: 0 init_lane_sync_stat: 0 8 lanes @ 13000000 kBps ad9172_init : AD936x Rev 1 successfully initialized tx_jesd status: Link is enabled Measured Link Clock: 119.511 MHz Reported Link Clock: 325.000 MHz Lane rate: 13000.000 MHz Lane rate / 40: 325.000 MHz LMFC rate: 40.625 MHz SYNC~: asserted Link status: CGS SYSREF captured: Yes SYSREF alignment error: Yes tx_dac: Successfully initialized (2087890625 Hz) Set dds frequency at 200MHz Bye
As you can see, it gets stuck in CGS mode, and no signal is coming out. Please guide us in some way to achieve what we are looking for, or it is even possible.
Thank you,
Alex