/** * \file ad9528.h * \brief Contains function declarations and ad9528Device_t structure typedef for ad9528.c */ /** * \page Disclaimer Legal Disclaimer * Copyright 2015-2017 Analog Devices Inc. * Released under the AD9371 API license. * */ #ifndef _AD9528_H_ #define _AD9528_H_ /******************************************************************************/ /***************************** Include Files **********************************/ /******************************************************************************/ #include #include "delay.h" #include "spi.h" #include "gpio.h" /******************************************************************************/ /********************** Macros and Constants Definitions **********************/ /******************************************************************************/ /* AD9528 SPI Address defines */ #define AD9528_ADDR_ADI_SPI_CONFIG_A 0x000 #define AD9528_ADDR_ADI_SPI_CONFIG_B 0x001 #define AD9528_ADDR_IO_UPDATE 0x00F #define AD9528_ADDR_REF_A_DIVIDER_LSB 0x100 #define AD9528_ADDR_REF_A_DIVIDER_MSB 0x101 #define AD9528_ADDR_REF_B_DIVIDER_LSB 0x102 #define AD9528_ADDR_REF_B_DIVIDER_MSB 0x103 #define AD9528_ADDR_PLL1_N_DIV_LSB 0x104 #define AD9528_ADDR_PLL1_N_DIV_MSB 0x105 #define AD9528_ADDR_PLL1_CHARGEPUMP 0x106 #define AD9528_ADDR_PLL1_CP_CTRL2 0x107 #define AD9528_ADDR_INPUT_RECEIVERS1 0x108 #define AD9528_ADDR_INPUT_RECEIVERS2 0x109 #define AD9528_ADDR_INPUT_RECEIVERS3 0x10A #define AD9528_ADDR_PLL1_FASTLOCK 0x10B #define AD9528_ADDR_PLL2_CHARGEPUMP 0x200 #define AD9528_ADDR_PLL2_N_DIV 0x201 #define AD9528_ADDR_PLL2_CTRL 0x202 #define AD9528_ADDR_PLL2_VCO_CTRL 0x203 #define AD9528_ADDR_PLL2_VCO_DIV 0x204 #define AD9528_ADDR_PLL2_LF_CTRL1 0x205 #define AD9528_ADDR_PLL2_LF_CTRL2 0x206 #define AD9528_ADDR_PLL2_RDIV 0x207 #define AD9528_ADDR_PLL2_REPLICA_CHDIV 0x208 #define AD9528_ADDR_PLL2_REPLICA_DIV_PHASE 0x209 #define AD9528_ADDR_CH_OUT0_CTRL1 0x300 #define AD9528_ADDR_CH_OUT0_CTRL2 0x301 #define AD9528_ADDR_CH_OUT0_CHDIV 0x302 #define AD9528_ADDR_OUTPUT_SYNC 0x32A #define AD9528_ADDR_MASK_SYNC1 0x32B #define AD9528_ADDR_MASK_SYNC2 0x32C #define AD9528_ADDR_EN_OUTPUT_PATH_SEL1 0x32D #define AD9528_ADDR_EN_OUTPUT_PATH_SEL2 0x32E #define AD9528_ADDR_SYSERF_DIV_LSB 0x400 #define AD9528_ADDR_SYSERF_DIV_MSB 0x401 #define AD9528_ADDR_SYSREF_CTRL3 0x402 #define AD9528_ADDR_SYSREF_CTRL4 0x403 #define AD9528_ADDR_SYSREF_CTRL5 0x404 #define AD9528_ADDR_POWERDOWN_CTRL 0x500 #define AD9528_ADDR_CH_POWERDOWN1 0x501 #define AD9528_ADDR_CH_POWERDOWN2 0x502 #define AD9528_ADDR_LDO_ENABLES1 0x503 #define AD9528_ADDR_LDO_ENABLES2 0x504 #define AD9528_ADDR_STATUS0_CTRL 0x505 #define AD9528_ADDR_STATUS1_CTRL 0x506 #define AD9528_ADDR_STATUS_OE 0x507 #define AD9528_ADDR_STATUS_READBACK0 0x508 #define AD9528_ADDR_STATUS_READBACK1 0x509 /******************************************************************************/ /*************************** Types Declarations *******************************/ /******************************************************************************/ ///Enum to select what source outputs from each AD9528 output channel typedef enum { AD9528_CHANNEL_DIV = 0, PLL1_OUTPUT = 1, //VCXO frequency SYSREF = 2, INV_PLL1_OUTPUT = 5 //VCXO inverted } ad9528outSourceSel_t; ///Enum to select what output buffer standard is used for the clock outputs typedef enum { AD9528_LVDS = 0, AD9528_LVDS_BOOST = 1, AD9528_HSTL = 2 } ad9528outBufferControl_t; ///Enum to select the clock input buffer mode. typedef enum { DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL } ad9528RefBuffer_t; /// Structure to hold AD9528 PLL1 settings typedef struct { uint32_t refA_Frequency_Hz; uint16_t refA_Divider; ad9528RefBuffer_t refA_bufferCtrl; uint32_t refB_Frequency_Hz; uint16_t refB_Divider; ad9528RefBuffer_t refB_bufferCtrl; uint32_t vcxo_Frequency_Hz; ad9528RefBuffer_t vcxoBufferCtrl; uint16_t nDivider; uint8_t bypassPll1; } ad9528pll1Settings_t; /// Structure to hold AD9528 PLL2 settings typedef struct { uint8_t rfDivider; //VCO divider: Valid range (3,4,5) uint8_t n2Divider; //PLL2 N2 Divider uint8_t totalNdiv; //NDiv = 4*Bdiv + Adiv //Bdiv valid range (3 to 63), Adiv valid range (0-3) } ad9528pll2Settings_t; /// Structure to hold AD9528 Output Clock settings typedef struct { uint16_t outPowerDown; //bit per output, if 1 power down that output. ad9528outSourceSel_t outSource[14]; //CHANNEL_DIV, PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT ad9528outBufferControl_t outBufferCtrl[14]; //LVDS, LVDS_BOOST, HSTL uint8_t outAnalogDelay[14]; //5 bits uint8_t outDigitalDelay[14]; //6 bits, 1/2 clock resolution @ channel div input frequency uint8_t outChannelDiv[14]; //8 bit channel divider uint32_t outFrequency_Hz[14]; //output clock frequency per clock output } ad9528outputSettings_t; ///Enum to select the SYSREF output source typedef enum { EXTERNAL = 0, EXT_RESAMPLED = 1, INTERNAL = 2 } sysrefSourceSelection_t; ///Enum to choose the SYSREF pattern mode. typedef enum { NSHOT = 0, CONTINUOUS = 1, PRBS = 2, STOP = 3 } sysrefPatternMode_t; ///Enum to select the SYSREF input pin mode. typedef enum { LEVEL_ACTIVE_HIGH = 0, LEVEL_ACTIVE_LOW = 1, RISING_EDGE = 2, FALLING_EDGE = 3 } sysrefPinEdgeMode_t; ///Enum to select the SYSREF output # of pulses for NSHOT mode. typedef enum { ONE_PULSE = 0, TWO_PULSES = 2, FOUR_PULSES = 3, SIX_PULSES = 4, EIGHT_PULSES = 5 } sysrefNshotMode_t; //Enum to select how a SYSREF is requested. typedef enum { SPI = 0, PIN = 1 } sysrefRequestMethod_t; /// Structure to hold AD9528 SYSREF output settings typedef struct { sysrefRequestMethod_t sysrefRequestMethod; sysrefSourceSelection_t sysrefSource; sysrefPinEdgeMode_t sysrefPinEdgeMode; ad9528RefBuffer_t sysrefPinBufferMode; sysrefPatternMode_t sysrefPatternMode; sysrefNshotMode_t sysrefNshotMode; uint16_t sysrefDivide; } ad9528sysrefSettings_t; /// Structure to hold AD9528 SPI settings typedef struct { uint8_t chipSelectIndex; ///< valid 1~8 uint8_t writeBitPolarity; ///< the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation uint8_t longInstructionWord; ///< 1 = 16bit instruction word, 0 = 8bit instruction word uint8_t MSBFirst; ///< 1 = MSBFirst, 0 = LSBFirst uint8_t CPHA; ///< clock phase, sets which clock edge the data updates (valid 0 or 1) uint8_t CPOL; ///< clock polarity 0 = clock starts low, 1 = clock starts high uint8_t enSpiStreaming; ///< Not implemented. SW feature to improve SPI throughput. uint8_t autoIncAddrUp; ///< Not implemented. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr = addr-1 uint8_t fourWireMode; ///< 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode. uint32_t spiClkFreq_Hz; ///< SPI Clk frequency in Hz (default 25000000), platform will use next lowest frequency that it's baud rate generator can create */ } ad9528spiSettings_t; /// Structure to hold AD9528 settings typedef struct { struct gpio_desc *gpio_resetb; struct gpio_desc *gpio_sysref_req; struct spi_desc *spi_desc; ad9528spiSettings_t *spiSettings; ad9528pll1Settings_t *pll1Settings; ad9528pll2Settings_t *pll2Settings; ad9528outputSettings_t *outputSettings; ad9528sysrefSettings_t *sysrefSettings; } ad9528Device_t; typedef struct { struct gpio_init_param *gpio_init_resetb; struct gpio_init_param *gpio_init_sysref_req; struct spi_init_param *spi_init; ad9528spiSettings_t *spiSettings; ad9528pll1Settings_t *pll1Settings; ad9528pll2Settings_t *pll2Settings; ad9528outputSettings_t *outputSettings; ad9528sysrefSettings_t *sysrefSettings; } ad9528Init_t; typedef enum { SYSREF_CONT_ON, SYSREF_CONT_OFF, SYSREF_PULSE, } ad9528SysrefReqMode_t; /******************************************************************************/ /************************ Functions Declarations ******************************/ /******************************************************************************/ //Helper function to setup the 9528 device data structure specifically for the ADI transceiver evaluation cards int32_t AD9528_initDeviceDataStruct(ad9528Device_t *device, uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz, uint32_t outputDeviceClock_Hz); int32_t AD9528_spiReadByte(ad9528Device_t *device, uint16_t addr, uint8_t *readdata); //AD9528 API functions int32_t AD9528_hasTimeoutExpired(); int32_t AD9528_resetDevice(ad9528Device_t *device); int32_t AD9528_init(ad9528Device_t **device, const ad9528Init_t *init_device); int32_t AD9528_config(ad9528Device_t *device); //writes all registers to desired values, leaves clock outputs off. int32_t AD9528_setupSYSREF(ad9528Device_t *device, uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode, sysrefNshotMode_t nShotPulses); int32_t AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF); int32_t AD9528_sysrefReq(ad9528Device_t *device, ad9528SysrefReqMode_t mode); int32_t AD9528_remove(ad9528Device_t *device); #endif