Post Go back to editing

AD9081 - Odd-numbered FDDCs (FDDC1, FDDC3, FDDC5, and FDDC7) are receiving zero data.

Thread Summary

The user is experiencing an issue where odd-numbered FDDCs (FDDC1, FDDC3, FDDC5, FDDC7) on the AD9081 ADC are receiving zero data, while even-numbered FDDCs are working correctly. The final answer suggests submitting the question to the Analog Devices Tech Support Center for further assistance. The JESD204B configuration and clock settings are provided, including L=4, F=8, M=16, S=1, K=32, N=16, NP=16, and ADC sampling at 1.6 GHz.
AI Generated Content
Category: Software
Software Version: AD9081 API: Rel1.7.0
Hello ADI team,

I am aiming to receive eight different types of signals from an ADC using the AD9081.

Current status:
・The JTX link is stable.
・Data communication via the JTX link is working, and NCO behavior has been confirmed.
・Even-numbered FDDCs (FDDC0, FDDC2, FDDC4, and FDDC6) are receiving data without issues. However, odd-numbered FDDCs (FDDC1, FDDC3, FDDC5, and FDDC7) are receiving zero data.

1) HW Configuration
- FPGA: ZU19EG, Linux (PetaLinux)
- DAC/ADC: AD9081
- Clock/SYSREF: HMC7044
- DAC LO: ADF4377
- JESD204B Subclass-1 configuration:
  - ADC (JTX): AD9081 → FPGA (JESD RX)

- AD9081 API: Rel1.7.0 (spidev HAL, custom)
- JESD Configuration (ADC→FPGA, JTX Link0):
  - JESD204B / 8B10B
JTX(ADC⇒FPGA)
  - `L=4, F=8, M=16, S=1, K=32, N=16, NP=16, scr=0, subclass=1` HD=0, CS=0
- ADC Sampling:
  - ADC Clock: 1.6 GHz (1.6 GSPS)
  - DDC Configuration (Current Bring-Up):
    - CDDC: 1/2 (AD9081_CDDC_DCM_2)
    - FDDC: 1/8 (AD9081_FDDC_DCM_8)
    - Total 1/16 → Effective 100 MSPS × 16 channels


2) JESD Clock Configuration
AD9081 DAC/ADC sample clock (ADCs’ Fs) and its source.
DAC: 4.8 GHz
ADC: 1.6 GHz
- FPGA GT refclk: 200 MHz
- SYSREF frequency: 0.78125 MHz
20 MHz crystal oscillator ⇒ HMC7044 ⇒ 400 MHz ⇒ ADF4377 ⇒ 4.8 GHz ⇒ AD9081 ⇒ AD9081 DAC clock
20 MHz crystal oscillator ⇒ HMC7044 ⇒ 400 MHz ⇒ ADF4377 ⇒ 4.8 GHz ⇒ AD9081 ⇒ AD9081 internal 1/3 divider ⇒ AD9081 ADC clock
20 MHz crystal oscillator ⇒ HMC7044 ⇒ 200 MHz ⇒ FPGA


3) Source code for the initialization process
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <linux/spi/spidev.h>

#include "adi_ad9081.h"
#include "adi_ad9081_hal.h"
#include "adi_cms_api_common.h"

typedef struct {
    int fd;
    const char *node;
    uint32_t speed_hz;
    uint8_t mode;
    uint8_t bits;
} ad9081_spidev_ctx_t;

void ad9081_linux_hal_attach(adi_ad9081_device_t *dev, ad9081_spidev_ctx_t *ctx);

static int die_if_err(const char *tag, int32_t rc)
{
    if (rc != API_CMS_ERROR_OK) {
        printf("FAIL %s rc=%d\n", tag, (int)rc);
        return -1;
    }
    return 0;
}

static void fill_jtx_conv_sel_straight(adi_ad9081_jtx_conv_sel_t *s)
{
    s->virtual_converter0_index = AD9081_FDDC_0_I;
    s->virtual_converter1_index = AD9081_FDDC_0_Q;
    s->virtual_converter2_index = AD9081_FDDC_1_I;
    s->virtual_converter3_index = AD9081_FDDC_1_Q;
    s->virtual_converter4_index = AD9081_FDDC_2_I;
    s->virtual_converter5_index = AD9081_FDDC_2_Q;
    s->virtual_converter6_index = AD9081_FDDC_3_I;
    s->virtual_converter7_index = AD9081_FDDC_3_Q;
    s->virtual_converter8_index = AD9081_FDDC_4_I;
    s->virtual_converter9_index = AD9081_FDDC_4_Q;
    s->virtual_convertera_index = AD9081_FDDC_5_I;
    s->virtual_converterb_index = AD9081_FDDC_5_Q;
    s->virtual_converterc_index = AD9081_FDDC_6_I;
    s->virtual_converterd_index = AD9081_FDDC_6_Q;
    s->virtual_convertere_index = AD9081_FDDC_7_I;
    s->virtual_converterf_index = AD9081_FDDC_7_Q;
}

static void fill_jtx_link0_param_mode12(adi_cms_jesd_param_t *p)
{
    memset(p, 0, sizeof(*p));
    p->jesd_l = 4;
    p->jesd_f = 8;
    p->jesd_m = 16;
    p->jesd_s = 1;
    p->jesd_hd = 0;
    p->jesd_k = 32;
    p->jesd_n = 16;
    p->jesd_np = 16;
    p->jesd_cs = 0;
    p->jesd_subclass = JESD_SUBCLASS_1;
    p->jesd_scr = 0;
    p->jesd_duallink = 0;
    p->jesd_jesdv = 1;      /* JESD204B */
    p->jesd_mode_id = 12;   /* mode12.0 */
    p->jesd_mode_s_sel = 0;
    p->jesd_mode_c2r_en = 0;
    p->jesd_did = 0;
    p->jesd_bid = 0;
    p->jesd_lid0 = 0;
}


int main(void)
{
    adi_ad9081_device_t dev;

    ad9081_spidev_ctx_t ctx = {
        .fd = -1,
        .node = "/dev/spidev0.0",
        .speed_hz = 1000000,
        .mode = (SPI_MODE_0 | SPI_CS_HIGH),
        .bits = 8
    };

    ad9081_linux_hal_attach(&dev, &ctx);

    if (die_if_err("hal_hw_open", adi_ad9081_hal_hw_open(&dev)) < 0) return 1;

    if (die_if_err("soft_reset", adi_ad9081_device_reset(&dev, AD9081_SOFT_RESET)) < 0) return 1;
    if (die_if_err("4wire", adi_ad9081_hal_reg_set(&dev, 0x0000, 0x18)) < 0) return 1;
    if (die_if_err("dev_init", adi_ad9081_device_init(&dev)) < 0) return 1;

    {
        uint64_t dac_clk_hz = 4800000000ULL;
        uint64_t adc_clk_hz = 1600000000ULL;
        uint64_t ref_clk_hz = 4800000000ULL;
        if (die_if_err("clk_cfg",
                       adi_ad9081_device_clk_config_set(&dev, dac_clk_hz, adc_clk_hz, ref_clk_hz)) < 0)
            return 1;
    }

    {
        uint8_t cddcs = AD9081_ADC_CDDC_ALL;
        uint8_t fddcs = AD9081_ADC_FDDC_ALL;

        int64_t cddc_shift[4] = {0, 0, 0, 0};
        int64_t fddc_shift[8] = {1000000LL, 2000000LL, 3000000LL, 4000000LL, 5000000LL, 6000000LL, 7000000LL, 8000000LL};

        uint8_t cddc_dcm[4] = {
            AD9081_CDDC_DCM_2, AD9081_CDDC_DCM_2,
            AD9081_CDDC_DCM_2, AD9081_CDDC_DCM_2
        };
        uint8_t fddc_dcm[8] = {
            AD9081_FDDC_DCM_8, AD9081_FDDC_DCM_8,
            AD9081_FDDC_DCM_8, AD9081_FDDC_DCM_8,
            AD9081_FDDC_DCM_8, AD9081_FDDC_DCM_8,
            AD9081_FDDC_DCM_8, AD9081_FDDC_DCM_8
        };

        uint8_t cc2r_en[4] = {0, 0, 0, 0};
        uint8_t fc2r_en[8] = {0, 0, 0, 0, 0, 0, 0, 0};

        adi_cms_jesd_param_t jtx_param[2];
        memset(jtx_param, 0, sizeof(jtx_param));
        fill_jtx_link0_param_mode12(&jtx_param[0]);

        adi_ad9081_jtx_conv_sel_t jesd_conv_sel[2];
        memset(jesd_conv_sel, 0, sizeof(jesd_conv_sel));
        fill_jtx_conv_sel_straight(&jesd_conv_sel[0]);

        int32_t rc = adi_ad9081_device_startup_rx(&dev,
                                                  cddcs, fddcs,
                                                  cddc_shift, fddc_shift,
                                                  cddc_dcm, fddc_dcm,
                                                  cc2r_en, fc2r_en,
                                                  jtx_param,
                                                  jesd_conv_sel);
        printf("startup_rx rc=%d\n", (int)rc);
        if (die_if_err("startup_rx", rc) < 0) return 1;
    }

    if (die_if_err("coarse_nco_mode_set",
                   adi_ad9081_adc_ddc_coarse_nco_mode_set(&dev, AD9081_ADC_CDDC_ALL, AD9081_ADC_NCO_ZIF)) < 0)
        return 1;

    {
        uint8_t adc_cddc_xbar = (uint8_t)AD9081_ADC_4_ADC_COMP_MODE;

        uint8_t cddc_fddc_xbar = 0;
        cddc_fddc_xbar  =
            AD9081_ADC_CDDC0_TO_FDDC0 |
            AD9081_ADC_CDDC0_TO_FDDC1 |
            AD9081_ADC_CDDC1_TO_FDDC2 |
            AD9081_ADC_CDDC1_TO_FDDC3;

        cddc_fddc_xbar |=
            AD9081_ADC_CDDC2_TO_FDDC4 |
            AD9081_ADC_CDDC2_TO_FDDC5 |
            AD9081_ADC_CDDC3_TO_FDDC6 |
            AD9081_ADC_CDDC3_TO_FDDC7;

        int32_t rc = adi_ad9081_adc_xbar_set(&dev, adc_cddc_xbar, cddc_fddc_xbar);
        printf("adc_xbar_set rc=%d\n", (int)rc);
        if (die_if_err("adc_xbar_set", rc) < 0) return 1;
    }

    {
        uint8_t tx_lane_map[8] = { 3, 2, 4, 5, 6, 7, 0, 1 };
        if (die_if_err("jtx_lanes_xbar",
                       adi_ad9081_jesd_tx_lanes_xbar_set(&dev, AD9081_LINK_0, tx_lane_map)) < 0)
            return 1;
    }

    {
        int32_t rc = adi_ad9081_jesd_oneshot_sync(&dev, JESD_SUBCLASS_1);
        if (rc == API_CMS_ERROR_OK) printf("oneshot:OK\n");
        else printf("oneshot:FAIL rc=%d\n", (int)rc);
    }

    if (die_if_err("jtx_en", adi_ad9081_jesd_tx_link_enable_set(&dev, AD9081_LINK_0, 1)) < 0) return 1;

    (void)adi_ad9081_hal_hw_close(&dev);
    return 0;
}
I suspect there might be an issue with the source code for the initialization process I'm using.
I would appreciate any advice you could offer.

Best regards.
Parents Reply Children
No Data