/***************************************************************************//** * @brief Configures the test mode and the output mode to a default state. * * @param spiBaseAddr - SPI peripheral AXI base address. * @param ssNo - Slave select line on which the slave is connected. * * @return Negative error code or 0 in case of success. *******************************************************************************/ int32_t ad9467_setup(int32_t spiBaseAddr, int32_t ssNo) { int32_t ret = 0; spiBaseAddress = spiBaseAddr; spiSlaveSelect = ssNo; /* Initializes the SPI peripheral */ ret = SPI_Init(spiBaseAddress, 0, 0, 0); if(ret < 0) { return ret; } /* Disable test mode. */ ret = ad9467_write(AD9467_REG_TEST_IO, 0x00); if(ret < 0) { return ret; } /* Enable digital output, disable output invert and set data format to binary offset. */ ret = ad9467_write(AD9467_REG_OUT_MODE, 0x08); if(ret < 0) { return ret; } ret = ad9467_transfer(); if(ret < 0) { return ret; } return 0; }
/***************************************************************************//** * @brief Configures the clock delay setting. * * @param delay - The clock delay setting in ps {0, 100, 200, ..., 3100, 3200}. Setting the delay to 0 disables the DCO output clock delay. * * @return Negative error code or the set clock delay. *******************************************************************************/ int32_t ad9467_dco_output_clock_delay(int32_t delay) { int32_t ret = 0; if(!delay) { ret = ad9467_write(AD9467_REG_OUT_DELAY, 0x00); if(ret < 0) { return ret; } } else if( delay <= 3200) { delay = (delay - 100) / 100; ret = ad9467_write(AD9467_REG_OUT_DELAY, AD9467_OUT_DELAY_DCO_DLY_EN | AD9467_OUT_DELAY_OUT_DLY(delay)); if(ret < 0) { return ret; } } else { ret = ad9467_read(AD9467_REG_OUT_DELAY); if(ret < 0) { return ret; } if(ret & AD9467_OUT_DELAY_DCO_DLY_EN) { ret = (ret & AD9467_OUT_DELAY_OUT_DLY(0x1F)) * 100 + 100; return ret; } else { return 0; } } return ret; }
/***************************************************************************//** * @brief Initializes the AD9467 FPGA core. * * @param dco_delay - ADC delay. * * @return None. *******************************************************************************/ void adc_setup(uint32_t dco_delay) { Xil_Out32((CF_BASEADDR + 0x040), 0x3); delay_ms(10); // setup device ad9467_write(AD9467_REG_TEST_IO, 0x05); // pn23 ad9467_write(AD9467_REG_DEVICE_UPDATE, 0x01); // update ad9467_write(AD9467_REG_DEVICE_UPDATE, 0x00); xil_printf("AD9467[0x016]: %02x\n\r", ad9467_read(AD9467_REG_OUT_PHASE)); // setup adc core Xil_Out32((CF_BASEADDR+0x44), 0x2); // DDR_EDGESEL active Xil_Out32((CF_BASEADDR+0x400), 0x3); // pn23 Xil_Out32((CF_BASEADDR+0x60), 0x0); // clear Delay Control Xil_Out32((CF_BASEADDR+0x60), 0x20F1F); // Setup Delay Control delay_ms(10); if (adc_delay(8, 1)) { xil_printf("AD9467[0x016]: %02x\n\r", ad9467_read(0x16)); ad9467_write(AD9467_REG_OUT_PHASE, 0x80); ad9467_write(AD9467_REG_DEVICE_UPDATE, 0x01); ad9467_write(AD9467_REG_DEVICE_UPDATE, 0x00); xil_printf("AD9467[0x016]: %02x\n\r", ad9467_read(0x16)); delay_ms(10); if (adc_delay(16, 1)) { xil_printf("adc_setup: can not set a zero error delay!\n\r"); } } }
/***************************************************************************//** * @brief Sets the offset adjustment. * * @param adj - The offset adjust value in LSBs from +127 to -128. * * @return Negative error code or the set offset adjustment. *******************************************************************************/ int32_t ad9467_offset_adj(int32_t adj) { int32_t ret = 0; if((adj >= -128) && (adj <= 127)) { ret = ad9467_write(AD9467_REG_OFFSET, adj); if(ret < 0) { return ret; } } else { return (ad9467_read(AD9467_REG_OFFSET)); } return ret; }
/***************************************************************************//** * @brief Initiates a transfer and waits for the operation to end. * * @return Negative error code or 0 in case of success. *******************************************************************************/ int32_t ad9467_transfer(void) { int32_t ret = 0; int8_t sw_bit = 0; ret = ad9467_write(AD9467_REG_DEVICE_UPDATE, AD9467_DEVICE_UPDATE_SW); if(ret < 0) { return ret; } do { ret = ad9467_read(AD9467_REG_DEVICE_UPDATE); if(ret < 0) { return ret; } sw_bit = ret & AD9467_REG_DEVICE_UPDATE; }while(sw_bit == 1); return 0; }
/***************************************************************************//** * @brief Sets a bit or a group of bits inside a register without modifying * the other bits. * * @param registerAddress - The address of the register to be written. * @param bitsValue - The value of the bit/bits. * @param mask - The bit/bits position in the register. * * @return Negative error code or 0 in case of success. *******************************************************************************/ uint32_t ad9467_set_bits_to_reg(uint16_t registerAddress, uint8_t bitsValue, uint8_t mask) { uint8_t regValue = 0; int32_t ret = 0; ret = ad9467_read(registerAddress); if(ret < 0) { return ret; } regValue = ret & (~mask); regValue |= bitsValue; ret = ad9467_write(registerAddress, regValue); if(ret < 0) { return ret; } return 0; }