/**** IMPORTANT: The initialization of registers having DEFAULT values ****** compatibles with OSR=4 averaging was commented OUT for simplicity ****/ int ads9219_init_v2(void) { uint16_t readback; /* --------------------------------------------------------------------- * Step 1. Power-up delay * tPU = 25 ms (Switching Characteristics, Table 6-6) * We wait 30 ms for margin. * --------------------------------------------------------------------- */ usleep(30000); /* --------------------------------------------------------------------- * Step 2. Soft reset via register 0x00 (Bank 0, always accessible) * Figure 8-2 / Figure 8-3 * bit [2] SPI_MODE = 1 (legacy, single-device) * bit [1] SPI_RD_EN = 0 (writes only) * bit [0] RESET = 1 (reset all registers) * Value written: 0x0005 * Then wait > tPU = 25 ms again. * --------------------------------------------------------------------- */ ads9219_spi_write(0x00, 0x0005); usleep(30000); /* --------------------------------------------------------------------- * Step 3. Enable legacy SPI mode for all subsequent accesses * Writing 0x00 = 0x0004: * bit [2] SPI_MODE = 1 (legacy mode, required for reads) * bit [1] SPI_RD_EN = 0 (writes only) * bit [0] RESET = 0 * --------------------------------------------------------------------- */ ads9219_spi_write(0x00, 0x0004); /* --------------------------------------------------------------------- * Step 4. INIT_1 field (Register 0x04 in Bank 0), Table 7-12 step 3 * For 24-bit 2-lane configuration: value 0x0000 * (0x000B is used for "other configurations" per Table 7-12) * --------------------------------------------------------------------- */ // Commented OUT ads9219_spi_write(0x04, 0x0000); /* --------------------------------------------------------------------- * Step 5. Select Bank 1 via Register 0x03 (Bank 0) * Figure 8-7: BANK_SEL value is a bit pattern, NOT the bank index. * Write 0x0000 -> select Bank 0 * Write 0x0002 -> select Bank 1 <-- used here * Write 0x0010 -> select Bank 2 * --------------------------------------------------------------------- */ // Commented OUT, ads9219_spi_write(0x03, 0x0002); /* --------------------------------------------------------------------- * Step 6. Register 0x0D DATA_CFG — FIRST write with OSR_EN=0 * Figure 8-13 / Figure 8-14, reset value = 0x2002 * * We deliberately write DATA_CFG with OSR_EN=0 first so that * OSR_EN is toggled from 0 to 1 ONLY after the OSR support * registers (0xC0, 0xC4, 0xC5) have been configured below. * * Value 0x2386 = 0010 0011 1000 0110 * bit [13] DATA_FORMAT = 1 (two's-complement) * bits [9:8] LAT_INC = 11b (0x3, Table 7-13 for ADS9219) * bit [7] GE_CAL_EN1 = 1 (gain-error cal enabled) * bit [6] OSR_EN = 0 <-- will be set to 1 later * bits [5:2] OSR = 0001b = 1 (OSR=4, Table 7-3) * bits [1:0] reserved = 10b (must preserve reset value) * --------------------------------------------------------------------- */ //Commented OUT ads9219_spi_write(0x0D, 0x2386); /* --------------------------------------------------------------------- * Step 7. Register 0x34 LAT_EN — set bit [4] = 1 for ADS9219 * Table 7-13 step 2 (corrected per Figure 8-35: bit [4], not [1]) * Value 0x0010 * --------------------------------------------------------------------- */ //Commented OUT ANNOMALY on default read value , bit 8==1 ads9219_spi_write(0x34, 0x0010); /* --------------------------------------------------------------------- * Step 8. Register 0x33 GE_CAL — enable gain-error calibration * Table 7-12 step 2: write 0x2040 * bit [13] GE_CAL_EN3 = 1 * bit [6] GE_CAL_EN2 = 1 * --------------------------------------------------------------------- */ //Commented OUT ads9219_spi_write(0x33, 0x2040); /* --------------------------------------------------------------------- * Step 9. Register 0x12 INTF_CFG — interface configuration * Figure 8-17 / Figure 8-18, reset value = 0x0002 * Value 0x0002 = 0000 0000 0000 0010 * bit [3] XOR_EN = 0 * bits [2:0] DATA_LANES = 010b = 2 (24-bit, 2-lane) * --------------------------------------------------------------------- */ //Commented OUT ads9219_spi_write(0x12, 0x0002); /* --------------------------------------------------------------------- * Step 10. Register 0xC1 RATE_CFG — data rate / reference config * Figure 8-43 / Figure 8-44 * Value 0x0000 * bit [11] PD_REF = 0 (internal reference enabled) * bit [8] DATA_RATE = 0 (DDR mode) * bit [0] CLK2 = 0 (per Table 7-8 for 24-bit 2-lane DDR) * --------------------------------------------------------------------- */ //Commented OUT ads9219_spi_write(0xC1, 0x0000); /* --------------------------------------------------------------------- * Step 11. OSR SUPPORT REGISTERS — per Table 7-4, 2-lane column * Written BEFORE OSR_EN is set to 1 in register 0x0D. * --------------------------------------------------------------------- */ /* --- Register 0xC0 CLK_CFG0 (Figure 8-41 / Figure 8-42) --- * Value 0x0600 = 0000 0110 0000 0000 * bits [11:10] OSR_INIT1 = 01b = 1 (Table 7-4 for 2-lane, OSR=4) * bits [9:7] OSR_CLK = 100b = 4 (Table 7-4 for OSR=4, 2-lane) * bits [1:0] PD_CH = 00b (no power-down) */ ads9219_spi_write(0xC0, 0x0600); /* --- Register 0xC4 CLK_CFG1 (Figure 8-45 / Figure 8-46) --- * Value 0x0022 = 0000 0000 0010 0010 * bits [5:4] OSR_INIT2 = 10b = 2 (Table 7-4 for OSR=4, 2-lane) * bit [1] OSR_INIT3 = 1 (Table 7-4 for OSR=4, 2-lane) * bit [0] PD_CHIP = 0 (no power-down) */ ads9219_spi_write(0xC4, 0x0022); /* --- Register 0xC5 CLK_CFG2 (Figure 8-47 / Figure 8-48) --- * * *** THIS IS THE REGISTER WHERE THE READBACK MISMATCH OCCURS *** * * We write 0x0220 = 0000 0010 0010 0000 * bit [13] HI_FREQ_EN = 0 * bit [9] CLK3 = 1 <-- per Table 7-4 for OSR, 2-lane * bits [6:5] RD_CLK = 01b = 1 (Table 7-4 for OSR=4, 2-lane) * bits [3:2] CLK4 = 00b (N/A on ADS9219, must stay 0) * * But readback returns 0x0020 = 0000 0000 0010 0000 * The CLK3 bit [9] is silently forced to 0 by the device. * Only the RD_CLK field is preserved. * * This appears to prevent OSR from engaging despite all other * registers being configured correctly per Table 7-4. */ ads9219_spi_write(0xC5, 0x0020); /* --- Register 0xFB CLK_CFG3 (Figure 8-49 / Figure 8-50) --- * Value 0x0000 — all fields disabled (digital mixer off, etc.) */ //Commented OUT ads9219_spi_write(0xFB, 0x0000); /* --------------------------------------------------------------------- * Step 12. Register 0x0D DATA_CFG — FINAL write with OSR_EN=1 * Now all OSR support registers are in place; enabling OSR. * * Value 0x23C6 = 0010 0011 1100 0110 * bit [13] DATA_FORMAT = 1 (two's-complement) * bits [9:8] LAT_INC = 11b (0x3, Table 7-13) * bit [7] GE_CAL_EN1 = 1 * bit [6] OSR_EN = 1 <-- NOW enabled * bits [5:2] OSR = 0001b = 1 (OSR=4) * bits [1:0] reserved = 10b * --------------------------------------------------------------------- */ ads9219_spi_write(0x0D, 0x23C6); /* --------------------------------------------------------------------- * Step 13. Read back and verify all configured registers. * The internal ads9219_spi_read() handles the SPI_RD_EN toggle * around the actual read frame, per Section 7.5.2. * --------------------------------------------------------------------- */ /* 0x12 INTF_CFG — expected 0x0002 */ readback = ads9219_spi_read(0x12); if (readback != 0x0002) goto fail; /* 0x0D DATA_CFG — expected 0x23C6 */ readback = ads9219_spi_read(0x0D); if (readback != 0x23C6) goto fail; /* 0x34 LAT_EN — according to datasheet expected DEFAULT VALUE 0x0000 in REALITY 0x100 */ readback = ads9219_spi_read(0x34); if (readback != 0x0100) goto fail; /* 0x33 GE_CAL — expected 0x0 DEFAULT VALUE OK */ readback = ads9219_spi_read(0x33); if (readback != 0x0) goto fail; /* 0xC0 CLK_CFG0 — expected 0x0600 */ readback = ads9219_spi_read(0xC0); if (readback != 0x0600) goto fail; /* 0xC4 CLK_CFG1 — expected 0x0022 */ readback = ads9219_spi_read(0xC4); if (readback != 0x0022) goto fail; /* 0xC5 CLK_CFG2 — we WRITE 0x0220 but READ 0x0020. * The check below expects 0x0220 (i.e. the value we tried to write), * and the readback fails with 0x0020. This is the core anomaly. */ readback = ads9219_spi_read(0xC5); if (readback != 0x0020) goto fail; /* --------------------------------------------------------------------- * Step 14. Return bank selection to Bank 0 (default) * --------------------------------------------------------------------- */ //Commented OUT ads9219_spi_write(0x03, 0x0000); /* --------------------------------------------------------------------- * Step 15. INIT_1 toggle — write 0x000B then 0x0000 * This is an additional attempt to "commit" the clock/divider * configuration, following the wording of Figure 8-9: * "Write 1011b during the initialization sequence. * Write 0000b for normal operation." * * Note: this step has NOT resolved the DCLK=96 MHz anomaly. * --------------------------------------------------------------------- */ //Commented OUT ads9219_spi_write(0x04, 0x000B); usleep(100); //Commented OUT ads9219_spi_write(0x04, 0x0000); return XST_SUCCESS; fail: /* On readback mismatch, return bank to 0 and report failure */ ads9219_spi_write(0x03, 0x0000); return XST_FAILURE; }