diff --git a/df_datalink_sp/src/config/app_config.h b/df_datalink_sp/src/config/app_config.h index 6768624..f789b68 100644 --- a/df_datalink_sp/src/config/app_config.h +++ b/df_datalink_sp/src/config/app_config.h @@ -23,7 +23,7 @@ #include "xparameters.h" /******** Software Version ********/ -#define _APP_VER 0x00010008 +#define _APP_VER 0x00010000 #define _APP_VER_MAIN ((_APP_VER & 0xFF000000) >> 24) #define _APP_VER_MINOR ((_APP_VER & 0x00FF0000) >> 16) @@ -92,16 +92,6 @@ #define AD9363A_DEVICE 0 /* set it 1 if AD9363A device is used, 0 otherwise */ #define HAVE_VERBOSE_MESSAGES /* Recommended during development prints errors and warnings */ // #define HAVE_DEBUG_MESSAGES /* For Debug purposes only */ -// -- AD9361 SPI Engine Configuration -#define AD9361_SPI_DEVICE_ID 0 -#define AD9361_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ -#define AD9361_SPI_ENGINE_MAX_SPEED 5000000 -#define AD9361_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR -#define AD9361_SPI_ENGINE_DATA_WIDTH 8 -#define AD9361_SPI_ENGINE_CS_DELAY 3 -#define AD9361_SPI_CS_AD9361_1 0x01 -#define AD9361_SPI_CS_AD9361_2 0x02 -#define AD9361_TIMEOUT_TH 2000 // AD9361 GPIO Configurations #define AD9361_GPIO_DEVICE_ID 0 #define AD9361_GPIO_OFFSET 54 @@ -109,57 +99,50 @@ #define AD9361_GPIO_OUTPUT 1 #define AD9361_GPIO_DISABLE 0 #define AD9361_GPIO_ENABLE 1 -// -- AD9361-1 -#define AD9361_1_TXNRX (AD9361_GPIO_OFFSET + 6) -#define AD9361_1_ENABLE (AD9361_GPIO_OFFSET + 7) -#define AD9361_1_EN_AGC (AD9361_GPIO_OFFSET + 8) -#define AD9361_1_RESET_B (AD9361_GPIO_OFFSET + 9) -#define AD9361_1_CTRL_OUT0 (AD9361_GPIO_OFFSET + 10) -#define AD9361_1_CTRL_OUT1 (AD9361_GPIO_OFFSET + 11) -#define AD9361_1_CTRL_OUT2 (AD9361_GPIO_OFFSET + 12) -#define AD9361_1_CTRL_OUT3 (AD9361_GPIO_OFFSET + 13) -#define AD9361_1_CTRL_OUT4 (AD9361_GPIO_OFFSET + 14) -#define AD9361_1_CTRL_OUT5 (AD9361_GPIO_OFFSET + 15) -#define AD9361_1_CTRL_OUT6 (AD9361_GPIO_OFFSET + 16) -#define AD9361_1_CTRL_OUT7 (AD9361_GPIO_OFFSET + 17) -#define AD9361_1_CTRL_IN0 (AD9361_GPIO_OFFSET + 18) -#define AD9361_1_CTRL_IN1 (AD9361_GPIO_OFFSET + 19) -#define AD9361_1_CTRL_IN2 (AD9361_GPIO_OFFSET + 20) -#define AD9361_1_CTRL_IN3 (AD9361_GPIO_OFFSET + 21) -// AD9361-2 -#define AD9361_2_TXNRX (AD9361_GPIO_OFFSET + 22) -#define AD9361_2_ENABLE (AD9361_GPIO_OFFSET + 23) -#define AD9361_2_EN_AGC (AD9361_GPIO_OFFSET + 24) -#define AD9361_2_RESET_B (AD9361_GPIO_OFFSET + 25) -#define AD9361_2_CTRL_OUT0 (AD9361_GPIO_OFFSET + 26) -#define AD9361_2_CTRL_OUT1 (AD9361_GPIO_OFFSET + 27) -#define AD9361_2_CTRL_OUT2 (AD9361_GPIO_OFFSET + 28) -#define AD9361_2_CTRL_OUT3 (AD9361_GPIO_OFFSET + 29) -#define AD9361_2_CTRL_OUT4 (AD9361_GPIO_OFFSET + 30) -#define AD9361_2_CTRL_OUT5 (AD9361_GPIO_OFFSET + 31) -#define AD9361_2_CTRL_OUT6 (AD9361_GPIO_OFFSET + 32) -#define AD9361_2_CTRL_OUT7 (AD9361_GPIO_OFFSET + 33) -#define AD9361_2_CTRL_IN0 (AD9361_GPIO_OFFSET + 34) -#define AD9361_2_CTRL_IN1 (AD9361_GPIO_OFFSET + 35) -#define AD9361_2_CTRL_IN2 (AD9361_GPIO_OFFSET + 36) -#define AD9361_2_CTRL_IN3 (AD9361_GPIO_OFFSET + 37) -// AD9361-Status Code -#define AD9361_SYNC (AD9361_GPIO_OFFSET + 38) -#define AD9361_RX_FIFO_RST (AD9361_GPIO_OFFSET + 39) -#define AD9361_1_CAL_START (AD9361_GPIO_OFFSET + 40) -#define AD9361_2_CAL_START (AD9361_GPIO_OFFSET + 41) -#define AD9361_RECAL (AD9361_GPIO_OFFSET + 42) -#define AD9361_TX_SWITCH (AD9361_GPIO_OFFSET + 43) -#define AD9361_1_CAL_DONE (AD9361_GPIO_OFFSET + 44) -#define AD9361_2_CAL_DONE (AD9361_GPIO_OFFSET + 45) -#define AD9361_CAL_RESULT (AD9361_GPIO_OFFSET + 46) - -typedef enum -{ - TX_FREQ_125, - TX_FREQ_126, - TX_FREQ_4125 -} ad9361TxFreq; +// -- AD9361 SPI Engine Configuration +#define AD9361_SPI_DEVICE_ID 0 +#define AD9361_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ +#define AD9361_SPI_ENGINE_MAX_SPEED 5000000 +#define AD9361_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR +#define AD9361_SPI_ENGINE_DATA_WIDTH 8 +#define AD9361_SPI_ENGINE_CS_DELAY 3 +#define AD9361_TIMEOUT_TH 2000 +#define AD9361_1_SPI_CS 0x01 +#define AD9361_2_SPI_CS 0x02 +// -- AD9361-1 GPIO +#define AD9361_1_TXNRX (AD9361_GPIO_OFFSET + 4) +#define AD9361_1_ENABLE (AD9361_GPIO_OFFSET + 5) +#define AD9361_1_EN_AGC (AD9361_GPIO_OFFSET + 6) +#define AD9361_1_RESET_B (AD9361_GPIO_OFFSET + 7) +#define AD9361_1_CTRL_OUT0 (AD9361_GPIO_OFFSET + 8) +#define AD9361_1_CTRL_OUT1 (AD9361_GPIO_OFFSET + 9) +#define AD9361_1_CTRL_OUT2 (AD9361_GPIO_OFFSET + 10) +#define AD9361_1_CTRL_OUT3 (AD9361_GPIO_OFFSET + 11) +#define AD9361_1_CTRL_OUT4 (AD9361_GPIO_OFFSET + 12) +#define AD9361_1_CTRL_OUT5 (AD9361_GPIO_OFFSET + 13) +#define AD9361_1_CTRL_OUT6 (AD9361_GPIO_OFFSET + 14) +#define AD9361_1_CTRL_OUT7 (AD9361_GPIO_OFFSET + 15) +#define AD9361_1_CTRL_IN0 (AD9361_GPIO_OFFSET + 16) +#define AD9361_1_CTRL_IN1 (AD9361_GPIO_OFFSET + 17) +#define AD9361_1_CTRL_IN2 (AD9361_GPIO_OFFSET + 18) +#define AD9361_1_CTRL_IN3 (AD9361_GPIO_OFFSET + 19) +// -- AD9361-2 GPIO +#define AD9361_2_TXNRX (AD9361_GPIO_OFFSET + 20) +#define AD9361_2_ENABLE (AD9361_GPIO_OFFSET + 21) +#define AD9361_2_EN_AGC (AD9361_GPIO_OFFSET + 22) +#define AD9361_2_RESET_B (AD9361_GPIO_OFFSET + 23) +#define AD9361_2_CTRL_OUT0 (AD9361_GPIO_OFFSET + 24) +#define AD9361_2_CTRL_OUT1 (AD9361_GPIO_OFFSET + 25) +#define AD9361_2_CTRL_OUT2 (AD9361_GPIO_OFFSET + 26) +#define AD9361_2_CTRL_OUT3 (AD9361_GPIO_OFFSET + 27) +#define AD9361_2_CTRL_OUT4 (AD9361_GPIO_OFFSET + 28) +#define AD9361_2_CTRL_OUT5 (AD9361_GPIO_OFFSET + 29) +#define AD9361_2_CTRL_OUT6 (AD9361_GPIO_OFFSET + 30) +#define AD9361_2_CTRL_OUT7 (AD9361_GPIO_OFFSET + 31) +#define AD9361_2_CTRL_IN0 (AD9361_GPIO_OFFSET + 32) +#define AD9361_2_CTRL_IN1 (AD9361_GPIO_OFFSET + 33) +#define AD9361_2_CTRL_IN2 (AD9361_GPIO_OFFSET + 34) +#define AD9361_2_CTRL_IN3 (AD9361_GPIO_OFFSET + 35) // HMC7044 Configurations #define HMC7044_GPIO_DEVICE_ID 0 @@ -177,7 +160,23 @@ typedef enum #define HMC7044_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR #define HMC7044_SPI_ENGINE_DATA_WIDTH 8 #define HMC7044_SPI_ENGINE_CS_DELAY 3 -#define HMC7044_SPI_CS_HMC7044 0x00 +#define HMC7044_SPI_CS 0x00 + +// AD9528 Configurations +#define AD9528_GPIO_DEVICE_ID 0 +#define AD9528_GPIO_OFFSET 54 +#define AD9528_RESETB (AD9528_GPIO_OFFSET+0) +#define AD9528_SYSREF_REQ (AD9528_GPIO_OFFSET+1) +#define AD9528_STATUS_0 (AD9528_GPIO_OFFSET+2) +#define AD9528_STATUS_1 (AD9528_GPIO_OFFSET+3) +// -- AD9528 SPI Engine Configuration +#define AD9528_SPI_DEVICE_ID 0 +#define AD9528_SPI_ENGINE_REF_CLK FCLK_CLK0_HZ +#define AD9528_SPI_ENGINE_MAX_SPEED 5000000 +#define AD9528_SPI_ENGINE_BASEADDR XPAR_AXI_SPI_ENGINE_AXI_SPI_ENGINE_BASEADDR +#define AD9528_SPI_ENGINE_DATA_WIDTH 8 +#define AD9528_SPI_ENGINE_CS_DELAY 3 +#define AD9528_SPI_CS 0x00 // Configuration Check #if defined(PHY_BEAM_SET_PRESET) && !defined(PHY_BEAM_FORMING_ENABLE) diff --git a/df_datalink_sp/src/dev_profile/ad9361_profile.c b/df_datalink_sp/src/dev_profile/ad9361_profile.c index 90de27b..a5d6817 100644 --- a/df_datalink_sp/src/dev_profile/ad9361_profile.c +++ b/df_datalink_sp/src/dev_profile/ad9361_profile.c @@ -273,7 +273,7 @@ AD9361_InitParam ad9361_default_init_param = { { .device_id = AD9361_SPI_DEVICE_ID, .mode = SPI_MODE_1, - .chip_select = AD9361_SPI_CS_AD9361_1, + .chip_select = AD9361_1_SPI_CS, .platform_ops = &spi_eng_platform_ops, .extra = &spi_engine_param }, diff --git a/df_datalink_sp/src/dev_profile/ad9361_reg_profile.c b/df_datalink_sp/src/dev_profile/ad9361_reg_profile.c index ce57c82..435edf8 100644 --- a/df_datalink_sp/src/dev_profile/ad9361_reg_profile.c +++ b/df_datalink_sp/src/dev_profile/ad9361_reg_profile.c @@ -25,7 +25,7 @@ static struct spi_init_param ad9361_1_reg_spi_init = { .device_id = AD9361_SPI_DEVICE_ID, .max_speed_hz = AD9361_SPI_ENGINE_MAX_SPEED, .mode = SPI_MODE_1, - .chip_select = AD9361_SPI_CS_AD9361_1, + .chip_select = AD9361_1_SPI_CS, .platform_ops = &spi_eng_platform_ops, .extra = &spi_engine_param }; @@ -35,6 +35,7 @@ static struct gpio_init_param ad9361_1_reg_gpio_resetb_init = { .platform_ops = &xil_gpio_ops, .extra = &xil_gpio_param }; + struct ad9361_reg_init_param ad9361_1_reg_default_init_param = { /* SPI */ .spi_init = &ad9361_1_reg_spi_init, @@ -46,7 +47,7 @@ static struct spi_init_param ad9361_2_reg_spi_init = { .device_id = AD9361_SPI_DEVICE_ID, .max_speed_hz = AD9361_SPI_ENGINE_MAX_SPEED, .mode = SPI_MODE_1, - .chip_select = AD9361_SPI_CS_AD9361_2, + .chip_select = AD9361_2_SPI_CS, .platform_ops = &spi_eng_platform_ops, .extra = &spi_engine_param }; @@ -56,6 +57,7 @@ static struct gpio_init_param ad9361_2_reg_gpio_resetb_init = { .platform_ops = &xil_gpio_ops, .extra = &xil_gpio_param }; + struct ad9361_reg_init_param ad9361_2_reg_default_init_param = { /* SPI */ .spi_init = &ad9361_2_reg_spi_init, @@ -72,7 +74,7 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ // generated using the AD9361 Customer software Version 2.1.3 //************************************************************ // Profile: Custom -// REFCLK_IN: 25.000 MHz +// REFCLK_IN: 40.000 MHz status = ad9361_reg_write(dev, 0x03DF, 0x01); // Required for proper operation @@ -87,527 +89,40 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ // Set BBPLL Frequency: 1152.000000 //************************************************************ status = ad9361_reg_write(dev, 0x0045, 0x03); // Set BBPLL reflclk scale to REFCLK * 2 - status = ad9361_reg_write(dev, 0x0046, 0x03); // Set BBPLL Loop Filter Charge Pump current + status = ad9361_reg_write(dev, 0x0046, 0x02); // Set BBPLL Loop Filter Charge Pump current status = ad9361_reg_write(dev, 0x0048, 0xE8); // Set BBPLL Loop Filter C1, R1 status = ad9361_reg_write(dev, 0x0049, 0x5B); // Set BBPLL Loop Filter R2, C2, C1 status = ad9361_reg_write(dev, 0x004A, 0x35); // Set BBPLL Loop Filter C3,R2 status = ad9361_reg_write(dev, 0x004B, 0xE0); // Allow calibration to occur and set cal count to 1024 for max accuracy status = ad9361_reg_write(dev, 0x004E, 0x10); // Set calibration clock to REFCLK/4 for more accuracy - status = ad9361_reg_write(dev, 0x0043, 0x66); // BBPLL Freq Word (Fractional[7:0]) - status = ad9361_reg_write(dev, 0x0042, 0x46); // BBPLL Freq Word (Fractional[15:8]) - status = ad9361_reg_write(dev, 0x0041, 0x01); // BBPLL Freq Word (Fractional[23:16]) - status = ad9361_reg_write(dev, 0x0044, 0x17); // BBPLL Freq Word (Integer[7:0]) + status = ad9361_reg_write(dev, 0x0043, 0x00); // BBPLL Freq Word (Fractional[7:0]) + status = ad9361_reg_write(dev, 0x0042, 0xC0); // BBPLL Freq Word (Fractional[15:8]) + status = ad9361_reg_write(dev, 0x0041, 0x0C); // BBPLL Freq Word (Fractional[23:16]) + status = ad9361_reg_write(dev, 0x0044, 0x0E); // BBPLL Freq Word (Integer[7:0]) status = ad9361_reg_write(dev, 0x003F, 0x05); // Start BBPLL Calibration status = ad9361_reg_write(dev, 0x003F, 0x01); // Clear BBPLL start calibration bit status = ad9361_reg_write(dev, 0x004C, 0x86); // Increase BBPLL KV and phase margin status = ad9361_reg_write(dev, 0x004D, 0x01); // Increase BBPLL KV and phase margin status = ad9361_reg_write(dev, 0x004D, 0x05); // Increase BBPLL KV and phase margin - // Wait for BBPLL to lock, Timeout 2sec, Max BBPLL VCO Cal Time: 276.480 us (Done when 0x05E[7]==1) + // Wait for BBPLL to lock, Timeout 2sec, Max BBPLL VCO Cal Time: 172.800 us (Done when 0x05E[7]==1) time_out_cnt = 0; do{ status |= ad9361_reg_read(dev, 0x005E, &value); mdelay(1);// Wait 1ms time_out_cnt++; - } while((value & 0x80) != 0x80 && time_out_cnt <= AD9361_TIMEOUT_TH); + } while((value & 0x80) != 0x80 && time_out_cnt <= TIMEOUT_TH); status = ad9361_reg_write(dev, 0x0002, 0xA4); // Setup Tx Digital Filters/ Channels - status = ad9361_reg_write(dev, 0x0003, 0xE5); // Setup Rx Digital Filters/ Channels + status = ad9361_reg_write(dev, 0x0003, 0xE4); // Setup Rx Digital Filters/ Channels status = ad9361_reg_write(dev, 0x0004, 0x03); // Select Rx input pin(A,B,C)/ Tx out pin (A,B) status = ad9361_reg_write(dev, 0x000A, 0x12); // Set BBPLL post divide rate -//************************************************************ -// Program Rx FIR: C:\Users\josh\Desktop\Config\rx64.txt -//************************************************************ - status = ad9361_reg_write(dev, 0x00F5, 0x9A); // Enable clock to Rx FIR Filter - status = ad9361_reg_write(dev, 0x00F6, 0x02); // Write Filter Gain setting - status = ad9361_reg_write(dev, 0x00F0, 0x00); // Write FIR coefficient address - status = ad9361_reg_write(dev, 0x00F1, 0x00); // Write FIR coefficient data[7:0] - status = ad9361_reg_write(dev, 0x00F2, 0x00); // Write FIR coefficient data[15:8] - status = ad9361_reg_write(dev, 0x00F5, 0x9E); // Set Write EN to push data into FIR filter register map - status = ad9361_reg_write(dev, 0x00F4, 0x00); // Dummy Write to Read only register to delay ~1us - status = ad9361_reg_write(dev, 0x00F4, 0x00); // Dummy Write to Read only register to delay ~1us - status = ad9361_reg_write(dev, 0x00F0, 0x01); - status = ad9361_reg_write(dev, 0x00F1, 0xB6); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x02); - status = ad9361_reg_write(dev, 0x00F1, 0xA5); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x03); - status = ad9361_reg_write(dev, 0x00F1, 0xEA); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x04); - status = ad9361_reg_write(dev, 0x00F1, 0x61); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x05); - status = ad9361_reg_write(dev, 0x00F1, 0xA3); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x06); - status = ad9361_reg_write(dev, 0x00F1, 0x4D); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x07); - status = ad9361_reg_write(dev, 0x00F1, 0x77); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x08); - status = ad9361_reg_write(dev, 0x00F1, 0xD5); - status = ad9361_reg_write(dev, 0x00F2, 0xFE); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x09); - status = ad9361_reg_write(dev, 0x00F1, 0x38); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x0A); - status = ad9361_reg_write(dev, 0x00F1, 0xA5); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x0B); - status = ad9361_reg_write(dev, 0x00F1, 0xF8); - status = ad9361_reg_write(dev, 0x00F2, 0x01); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x0C); - status = ad9361_reg_write(dev, 0x00F1, 0xAD); - status = ad9361_reg_write(dev, 0x00F2, 0x01); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x0D); - status = ad9361_reg_write(dev, 0x00F1, 0x75); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x0E); - status = ad9361_reg_write(dev, 0x00F1, 0xFD); - status = ad9361_reg_write(dev, 0x00F2, 0xFC); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x0F); - status = ad9361_reg_write(dev, 0x00F1, 0xD8); - status = ad9361_reg_write(dev, 0x00F2, 0xFC); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x10); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x11); - status = ad9361_reg_write(dev, 0x00F1, 0x3A); - status = ad9361_reg_write(dev, 0x00F2, 0x04); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x12); - status = ad9361_reg_write(dev, 0x00F1, 0x6B); - status = ad9361_reg_write(dev, 0x00F2, 0x05); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x13); - status = ad9361_reg_write(dev, 0x00F1, 0x51); - status = ad9361_reg_write(dev, 0x00F2, 0x01); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x14); - status = ad9361_reg_write(dev, 0x00F1, 0x80); - status = ad9361_reg_write(dev, 0x00F2, 0xFA); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x15); - status = ad9361_reg_write(dev, 0x00F1, 0x34); - status = ad9361_reg_write(dev, 0x00F2, 0xF7); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x16); - status = ad9361_reg_write(dev, 0x00F1, 0x08); - status = ad9361_reg_write(dev, 0x00F2, 0xFC); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x17); - status = ad9361_reg_write(dev, 0x00F1, 0xB2); - status = ad9361_reg_write(dev, 0x00F2, 0x06); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x18); - status = ad9361_reg_write(dev, 0x00F1, 0x1A); - status = ad9361_reg_write(dev, 0x00F2, 0x0E); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x19); - status = ad9361_reg_write(dev, 0x00F1, 0x44); - status = ad9361_reg_write(dev, 0x00F2, 0x09); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x1A); - status = ad9361_reg_write(dev, 0x00F1, 0x54); - status = ad9361_reg_write(dev, 0x00F2, 0xF8); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x1B); - status = ad9361_reg_write(dev, 0x00F1, 0xD1); - status = ad9361_reg_write(dev, 0x00F2, 0xE7); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x1C); - status = ad9361_reg_write(dev, 0x00F1, 0xC2); - status = ad9361_reg_write(dev, 0x00F2, 0xE9); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x1D); - status = ad9361_reg_write(dev, 0x00F1, 0x4F); - status = ad9361_reg_write(dev, 0x00F2, 0x08); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x1E); - status = ad9361_reg_write(dev, 0x00F1, 0xB2); - status = ad9361_reg_write(dev, 0x00F2, 0x3B); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x1F); - status = ad9361_reg_write(dev, 0x00F1, 0x2A); - status = ad9361_reg_write(dev, 0x00F2, 0x6C); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x20); - status = ad9361_reg_write(dev, 0x00F1, 0xFF); - status = ad9361_reg_write(dev, 0x00F2, 0x7F); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x21); - status = ad9361_reg_write(dev, 0x00F1, 0x2A); - status = ad9361_reg_write(dev, 0x00F2, 0x6C); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x22); - status = ad9361_reg_write(dev, 0x00F1, 0xB2); - status = ad9361_reg_write(dev, 0x00F2, 0x3B); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x23); - status = ad9361_reg_write(dev, 0x00F1, 0x4F); - status = ad9361_reg_write(dev, 0x00F2, 0x08); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x24); - status = ad9361_reg_write(dev, 0x00F1, 0xC2); - status = ad9361_reg_write(dev, 0x00F2, 0xE9); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x25); - status = ad9361_reg_write(dev, 0x00F1, 0xD1); - status = ad9361_reg_write(dev, 0x00F2, 0xE7); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x26); - status = ad9361_reg_write(dev, 0x00F1, 0x54); - status = ad9361_reg_write(dev, 0x00F2, 0xF8); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x27); - status = ad9361_reg_write(dev, 0x00F1, 0x44); - status = ad9361_reg_write(dev, 0x00F2, 0x09); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x28); - status = ad9361_reg_write(dev, 0x00F1, 0x1A); - status = ad9361_reg_write(dev, 0x00F2, 0x0E); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x29); - status = ad9361_reg_write(dev, 0x00F1, 0xB2); - status = ad9361_reg_write(dev, 0x00F2, 0x06); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x2A); - status = ad9361_reg_write(dev, 0x00F1, 0x08); - status = ad9361_reg_write(dev, 0x00F2, 0xFC); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x2B); - status = ad9361_reg_write(dev, 0x00F1, 0x34); - status = ad9361_reg_write(dev, 0x00F2, 0xF7); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x2C); - status = ad9361_reg_write(dev, 0x00F1, 0x80); - status = ad9361_reg_write(dev, 0x00F2, 0xFA); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x2D); - status = ad9361_reg_write(dev, 0x00F1, 0x51); - status = ad9361_reg_write(dev, 0x00F2, 0x01); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x2E); - status = ad9361_reg_write(dev, 0x00F1, 0x6B); - status = ad9361_reg_write(dev, 0x00F2, 0x05); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x2F); - status = ad9361_reg_write(dev, 0x00F1, 0x3A); - status = ad9361_reg_write(dev, 0x00F2, 0x04); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x30); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x31); - status = ad9361_reg_write(dev, 0x00F1, 0xD8); - status = ad9361_reg_write(dev, 0x00F2, 0xFC); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x32); - status = ad9361_reg_write(dev, 0x00F1, 0xFD); - status = ad9361_reg_write(dev, 0x00F2, 0xFC); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x33); - status = ad9361_reg_write(dev, 0x00F1, 0x75); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x34); - status = ad9361_reg_write(dev, 0x00F1, 0xAD); - status = ad9361_reg_write(dev, 0x00F2, 0x01); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x35); - status = ad9361_reg_write(dev, 0x00F1, 0xF8); - status = ad9361_reg_write(dev, 0x00F2, 0x01); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x36); - status = ad9361_reg_write(dev, 0x00F1, 0xA5); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x37); - status = ad9361_reg_write(dev, 0x00F1, 0x38); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x38); - status = ad9361_reg_write(dev, 0x00F1, 0xD5); - status = ad9361_reg_write(dev, 0x00F2, 0xFE); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x39); - status = ad9361_reg_write(dev, 0x00F1, 0x77); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x3A); - status = ad9361_reg_write(dev, 0x00F1, 0x4D); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x3B); - status = ad9361_reg_write(dev, 0x00F1, 0xA3); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x3C); - status = ad9361_reg_write(dev, 0x00F1, 0x61); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x3D); - status = ad9361_reg_write(dev, 0x00F1, 0xEA); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x3E); - status = ad9361_reg_write(dev, 0x00F1, 0xA5); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x3F); - status = ad9361_reg_write(dev, 0x00F1, 0xB6); - status = ad9361_reg_write(dev, 0x00F2, 0xFF); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x40); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x41); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x42); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x43); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x44); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x45); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x46); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x47); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x48); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x49); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x4A); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x4B); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x4C); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x4D); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x4E); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F0, 0x4F); - status = ad9361_reg_write(dev, 0x00F1, 0x00); - status = ad9361_reg_write(dev, 0x00F2, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x9E); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F4, 0x00); - status = ad9361_reg_write(dev, 0x00F5, 0x98); // Disable clock to Rx Filter - //************************************************************ // Setup the Parallel Port (Digital Data Interface) //************************************************************ - status = ad9361_reg_write(dev, 0x0010, 0xC8); // I/O Config. Tx Swap IQ; Rx Swap IQ; Tx CH Swap, Rx CH Swap; Rx Frame Mode; 2R2T bit; Invert data bus; Invert DATA_CLK + status = ad9361_reg_write(dev, 0x0010, 0xCC); // I/O Config. Tx Swap IQ; Rx Swap IQ; Tx CH Swap, Rx CH Swap; Rx Frame Mode; 2R2T bit; Invert data bus; Invert DATA_CLK status = ad9361_reg_write(dev, 0x0011, 0x00); // I/O Config. Alt Word Order; -Rx1; -Rx2; -Tx1; -Tx2; Invert Rx Frame; Delay Rx Data status = ad9361_reg_write(dev, 0x0012, 0x02); // I/O Config. Rx=2*Tx; Swap Ports; SDR; LVDS; Half Duplex; Single Port; Full Port; Swap Bits status = ad9361_reg_write(dev, 0x0006, 0x00); // PPORT Rx Delay (adjusts Tco Dataclk->Data) @@ -646,7 +161,7 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ //************************************************************ // Setup GPO //************************************************************ - status = ad9361_reg_write(dev, 0x003A, 0x18); // Set number of REFCLK cycles for 1us delay timer + status = ad9361_reg_write(dev, 0x003A, 0x27); // Set number of REFCLK cycles for 1us delay timer status = ad9361_reg_write(dev, 0x0020, 0x00); // GPO Auto Enable Setup in RX and TX status = ad9361_reg_write(dev, 0x0027, 0x00); // GPO Manual and GPO auto value in ALERT status = ad9361_reg_write(dev, 0x0028, 0x00); // GPO_0 RX Delay @@ -683,74 +198,74 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ status = ad9361_reg_write(dev, 0x023D, 0x04); // Start RX CP cal - // Wait for CP cal to complete, Max RXCP Cal time: 737.280 (us)(Done when 0x244[7]==1) + // Wait for CP cal to complete, Max RXCP Cal time: 460.800 (us)(Done when 0x244[7]==1) time_out_cnt = 0; do{ status |= ad9361_reg_read(dev, 0x0244, &value); mdelay(1);// Wait 1ms time_out_cnt++; - } while((value & 0x80) != 0x80 && time_out_cnt <= AD9361_TIMEOUT_TH); + } while((value & 0x80) != 0x80 && time_out_cnt <= TIMEOUT_TH); status = ad9361_reg_write(dev, 0x027D, 0x04); // Start TX CP cal - // Wait for CP cal to complete, Max TXCP Cal time: 737.280 (us)(Done when 0x284[7]==1) + // Wait for CP cal to complete, Max TXCP Cal time: 460.800 (us)(Done when 0x284[7]==1) time_out_cnt = 0; do{ status |= ad9361_reg_read(dev, 0x0284, &value); mdelay(1);// Wait 1ms time_out_cnt++; - } while((value & 0x80) != 0x80 && time_out_cnt <= AD9361_TIMEOUT_TH); + } while((value & 0x80) != 0x80 && time_out_cnt <= TIMEOUT_TH); status = ad9361_reg_write(dev, 0x023D, 0x00); // Disable RX CP Calibration since the CP Cal start bit is not self-clearing. Only important if the script is run again without restting the DUT status = ad9361_reg_write(dev, 0x027D, 0x00); // Disable TX CP Calibration since the CP Cal start bit is not self-clearing. Only important if the script is run again without restting the DUT //************************************************************ -// FDD RX,TX Synth Frequency: 125.000000,4125.000000 MHz +// FDD RX,TX Synth Frequency: 1268.250000,1268.250000 MHz //************************************************************ //************************************************************ // Setup Rx Frequency-Dependent Syntheisizer Registers //************************************************************ status = ad9361_reg_write(dev, 0x023A, 0x4A); // Set VCO Output level[3:0] - status = ad9361_reg_write(dev, 0x0239, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] - status = ad9361_reg_write(dev, 0x0242, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] - status = ad9361_reg_write(dev, 0x0238, 0x78); // Set VCO Cal Offset[3:0] + status = ad9361_reg_write(dev, 0x0239, 0xC0); // Set Init ALC Value[3:0] and VCO Varactor[3:0] + status = ad9361_reg_write(dev, 0x0242, 0x0D); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] + status = ad9361_reg_write(dev, 0x0238, 0x70); // Set VCO Cal Offset[3:0] status = ad9361_reg_write(dev, 0x0245, 0x00); // Set VCO Cal Ref Tcf[2:0] - status = ad9361_reg_write(dev, 0x0251, 0x0B); // Set VCO Varactor Reference[3:0] + status = ad9361_reg_write(dev, 0x0251, 0x09); // Set VCO Varactor Reference[3:0] status = ad9361_reg_write(dev, 0x0250, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] - status = ad9361_reg_write(dev, 0x023B, 0x94); // Set Synth Loop Filter charge pump current (Icp) - status = ad9361_reg_write(dev, 0x023E, 0xF4); // Set Synth Loop Filter C2 and C1 + status = ad9361_reg_write(dev, 0x023B, 0x8F); // Set Synth Loop Filter charge pump current (Icp) + status = ad9361_reg_write(dev, 0x023E, 0xD4); // Set Synth Loop Filter C2 and C1 status = ad9361_reg_write(dev, 0x023F, 0xDF); // Set Synth Loop Filter R1 and C3 - status = ad9361_reg_write(dev, 0x0240, 0x0A); // Set Synth Loop Filter R3 + status = ad9361_reg_write(dev, 0x0240, 0x09); // Set Synth Loop Filter R3 //************************************************************ // Setup Tx Frequency-Dependent Syntheisizer Registers //************************************************************ status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0] - status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] - status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] - status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0] + status = ad9361_reg_write(dev, 0x0279, 0xC0); // Set Init ALC Value[3:0] and VCO Varactor[3:0] + status = ad9361_reg_write(dev, 0x0282, 0x0D); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] + status = ad9361_reg_write(dev, 0x0278, 0x70); // Set VCO Cal Offset[3:0] status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0] - status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0] + status = ad9361_reg_write(dev, 0x0291, 0x09); // Set VCO Varactor Reference[3:0] status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] - status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp) - status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1 + status = ad9361_reg_write(dev, 0x027B, 0x8F); // Set Synth Loop Filter charge pump current (Icp) + status = ad9361_reg_write(dev, 0x027E, 0xD4); // Set Synth Loop Filter C2 and C1 status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3 - status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3 + status = ad9361_reg_write(dev, 0x0280, 0x09); // Set Synth Loop Filter R3 //************************************************************ // Write Rx and Tx Frequency Words //************************************************************ - status = ad9361_reg_write(dev, 0x0233, 0x00); // Write Rx Synth Fractional Freq Word[7:0] - status = ad9361_reg_write(dev, 0x0234, 0x00); // Write Rx Synth Fractional Freq Word[15:8] - status = ad9361_reg_write(dev, 0x0235, 0x00); // Write Rx Synth Fractional Freq Word[22:16] + status = ad9361_reg_write(dev, 0x0233, 0x8D); // Write Rx Synth Fractional Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0234, 0x99); // Write Rx Synth Fractional Freq Word[15:8] + status = ad9361_reg_write(dev, 0x0235, 0x69); // Write Rx Synth Fractional Freq Word[22:16] status = ad9361_reg_write(dev, 0x0232, 0x00); // Write Rx Synth Integer Freq Word[10:8] - status = ad9361_reg_write(dev, 0x0231, 0xA0); // Write Rx Synth Integer Freq Word[7:0] - status = ad9361_reg_write(dev, 0x0005, 0x05); // Set LO divider setting - status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0] - status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8] - status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16] + status = ad9361_reg_write(dev, 0x0231, 0x7E); // Write Rx Synth Integer Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0005, 0x22); // Set LO divider setting + status = ad9361_reg_write(dev, 0x0273, 0x8D); // Write Tx Synth Fractional Freq Word[7:0] + status = ad9361_reg_write(dev, 0x0274, 0x99); // Write Tx Synth Fractional Freq Word[15:8] + status = ad9361_reg_write(dev, 0x0275, 0x69); // Write Tx Synth Fractional Freq Word[22:16] status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8] - status = ad9361_reg_write(dev, 0x0271, 0xA5); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) - status = ad9361_reg_write(dev, 0x0005, 0x05); // Set LO divider setting + status = ad9361_reg_write(dev, 0x0271, 0x7E); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) + status = ad9361_reg_write(dev, 0x0005, 0x22); // Set LO divider setting //************************************************************ // Program Mixer GM Sub-table @@ -1542,12 +1057,12 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ status = ad9361_reg_write(dev, 0x011A, 0x27); // Initial LMT Gain Limit status = ad9361_reg_write(dev, 0x0081, 0x00); // Tx Symbol Gain Control //************************************************************ -// RX Baseband Filter Tuning (Real BW: 7.500000 MHz) 3dB Filter -// Corner @ 10.500000 MHz) +// RX Baseband Filter Tuning (Real BW: 20.000000 MHz) 3dB Filter +// Corner @ 28.000000 MHz) //************************************************************ - status = ad9361_reg_write(dev, 0x01FB, 0x07); // RX Freq Corner (MHz) - status = ad9361_reg_write(dev, 0x01FC, 0x40); // RX Freq Corner (Khz) - status = ad9361_reg_write(dev, 0x01F8, 0x0D); // Rx BBF Tune Divider[7:0] + status = ad9361_reg_write(dev, 0x01FB, 0x14); // RX Freq Corner (MHz) + status = ad9361_reg_write(dev, 0x01FC, 0x00); // RX Freq Corner (Khz) + status = ad9361_reg_write(dev, 0x01F8, 0x05); // Rx BBF Tune Divider[7:0] status = ad9361_reg_write(dev, 0x01F9, 0x1E); // RX BBF Tune Divider[8] status = ad9361_reg_write(dev, 0x01D5, 0x3F); // Set Rx Mix LO CM @@ -1556,56 +1071,56 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ status = ad9361_reg_write(dev, 0x01E3, 0x02); // Enable Rx2 Filter Tuner status = ad9361_reg_write(dev, 0x0016, 0x80); // Start RX Filter Tune - // Wait for RX filter to tune, Max Cal Time: 6.884 us (Done when 0x016[7]==0) + // Wait for RX filter to tune, Max Cal Time: 2.648 us (Done when 0x016[7]==0) time_out_cnt = 0; do{ status |= ad9361_reg_read(dev, 0x0016, &value); mdelay(1);// Wait 1ms time_out_cnt++; - } while((value & 0x80) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + } while((value & 0x80) != 0x00 && time_out_cnt <= TIMEOUT_TH); status = ad9361_reg_write(dev, 0x01E2, 0x03); // Disable Rx Filter Tuner (Rx1) status = ad9361_reg_write(dev, 0x01E3, 0x03); // Disable Rx Filter Tuner (Rx2) //************************************************************ -// TX Baseband Filter Tuning (Real BW: 7.500000 MHz) 3dB Filter -// Corner @ 12.000000 MHz) +// TX Baseband Filter Tuning (Real BW: 20.000000 MHz) 3dB Filter +// Corner @ 32.000000 MHz) //************************************************************ - status = ad9361_reg_write(dev, 0x00D6, 0x0B); // TX BBF Tune Divider[7:0] + status = ad9361_reg_write(dev, 0x00D6, 0x04); // TX BBF Tune Divider[7:0] status = ad9361_reg_write(dev, 0x00D7, 0x1E); // TX BBF Tune Divider[8] status = ad9361_reg_write(dev, 0x00CA, 0x22); // Enable Tx Filter Tuner status = ad9361_reg_write(dev, 0x0016, 0x40); // Start Tx Filter Tune - // Wait for TX filter to tune, Max Cal Time: 3.390 us (Done when 0x016[6]==0) + // Wait for TX filter to tune, Max Cal Time: 1.233 us (Done when 0x016[6]==0) time_out_cnt = 0; do{ status |= ad9361_reg_read(dev, 0x0016, &value); mdelay(1);// Wait 1ms time_out_cnt++; - } while((value & 0x40) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + } while((value & 0x40) != 0x00 && time_out_cnt <= TIMEOUT_TH); status = ad9361_reg_write(dev, 0x00CA, 0x26); // Disable Tx Filter Tuner (Both Channels) //************************************************************ // RX TIA Setup: Setup values scale based on RxBBF calibration // results. See information in Calibration Guide. //************************************************************ - status = ad9361_reg_write(dev, 0x01DB, 0x60); // Set TIA selcc[2:0] + status = ad9361_reg_write(dev, 0x01DB, 0x20); // Set TIA selcc[2:0] status = ad9361_reg_write(dev, 0x01DD, 0x00); // Set RX TIA1 C MSB[6:0] status = ad9361_reg_write(dev, 0x01DF, 0x00); // Set RX TIA2 C MSB[6:0] - status = ad9361_reg_write(dev, 0x01DC, 0x72); // Set RX TIA1 C LSB[5:0] - status = ad9361_reg_write(dev, 0x01DE, 0x72); // Set RX TIA2 C LSB[5:0] + status = ad9361_reg_write(dev, 0x01DC, 0x47); // Set RX TIA1 C LSB[5:0] + status = ad9361_reg_write(dev, 0x01DE, 0x47); // Set RX TIA2 C LSB[5:0] //************************************************************ // TX Secondary Filter Calibration Setup: Real Bandwidth -// 7.500000MHz, 3dB Corner @ 37.500000MHz +// 20.000000MHz, 3dB Corner @ 100.000000MHz //************************************************************ - status = ad9361_reg_write(dev, 0x00D2, 0x1E); // TX Secondary Filter PDF Cap cal[5:0] + status = ad9361_reg_write(dev, 0x00D2, 0x04); // TX Secondary Filter PDF Cap cal[5:0] status = ad9361_reg_write(dev, 0x00D1, 0x0C); // TX Secondary Filter PDF Res cal[3:0] - status = ad9361_reg_write(dev, 0x00D0, 0x56); // Pdampbias + status = ad9361_reg_write(dev, 0x00D0, 0x57); // Pdampbias //************************************************************ // ADC Setup: Tune ADC Performance based on RX analog filter tune -// corner. Real Bandwidth: 6.982753 MHz, ADC Clock Frequency: +// corner. Real Bandwidth: 18.155158 MHz, ADC Clock Frequency: // 288.000000 MHz. The values in registers 0x200 - 0x227 need to be // calculated using the equations in the Calibration Guide. //************************************************************ @@ -1617,23 +1132,23 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ status = ad9361_reg_write(dev, 0x0204, 0x24); status = ad9361_reg_write(dev, 0x0205, 0x00); status = ad9361_reg_write(dev, 0x0206, 0x00); - status = ad9361_reg_write(dev, 0x0207, 0x7C); - status = ad9361_reg_write(dev, 0x0208, 0x46); - status = ad9361_reg_write(dev, 0x0209, 0x3C); - status = ad9361_reg_write(dev, 0x020A, 0x4C); - status = ad9361_reg_write(dev, 0x020B, 0x2C); - status = ad9361_reg_write(dev, 0x020C, 0x4F); - status = ad9361_reg_write(dev, 0x020D, 0x2A); + status = ad9361_reg_write(dev, 0x0207, 0x67); + status = ad9361_reg_write(dev, 0x0208, 0x55); + status = ad9361_reg_write(dev, 0x0209, 0x31); + status = ad9361_reg_write(dev, 0x020A, 0x3E); + status = ad9361_reg_write(dev, 0x020B, 0x35); + status = ad9361_reg_write(dev, 0x020C, 0x41); + status = ad9361_reg_write(dev, 0x020D, 0x34); status = ad9361_reg_write(dev, 0x020E, 0x00); - status = ad9361_reg_write(dev, 0x020F, 0x7F); - status = ad9361_reg_write(dev, 0x0210, 0x7F); - status = ad9361_reg_write(dev, 0x0211, 0x7F); - status = ad9361_reg_write(dev, 0x0212, 0x4A); - status = ad9361_reg_write(dev, 0x0213, 0x4A); - status = ad9361_reg_write(dev, 0x0214, 0x4A); - status = ad9361_reg_write(dev, 0x0215, 0x4D); - status = ad9361_reg_write(dev, 0x0216, 0x4D); - status = ad9361_reg_write(dev, 0x0217, 0x4D); + status = ad9361_reg_write(dev, 0x020F, 0x6A); + status = ad9361_reg_write(dev, 0x0210, 0x6A); + status = ad9361_reg_write(dev, 0x0211, 0x6A); + status = ad9361_reg_write(dev, 0x0212, 0x3C); + status = ad9361_reg_write(dev, 0x0213, 0x3C); + status = ad9361_reg_write(dev, 0x0214, 0x3C); + status = ad9361_reg_write(dev, 0x0215, 0x3F); + status = ad9361_reg_write(dev, 0x0216, 0x3F); + status = ad9361_reg_write(dev, 0x0217, 0x3F); status = ad9361_reg_write(dev, 0x0218, 0x2E); status = ad9361_reg_write(dev, 0x0219, 0x9C); status = ad9361_reg_write(dev, 0x021A, 0x1F); @@ -1664,7 +1179,7 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ status |= ad9361_reg_read(dev, 0x0016, &value); mdelay(1);// Wait 1ms time_out_cnt++; - } while((value & 0x01) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + } while((value & 0x01) != 0x00 && time_out_cnt <= TIMEOUT_TH); status = ad9361_reg_write(dev, 0x0185, 0x20); // Set RF DC offset Wait Count status = ad9361_reg_write(dev, 0x0186, 0x32); // Set RF DC Offset Count[7:0] @@ -1680,21 +1195,21 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ status |= ad9361_reg_read(dev, 0x0016, &value); mdelay(1);// Wait 1ms time_out_cnt++; - } while((value & 0x01) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + } while((value & 0x01) != 0x00 && time_out_cnt <= TIMEOUT_TH); //************************************************************ // Tx Quadrature Calibration Settings //************************************************************ - status = ad9361_reg_write(dev, 0x00A0, 0x15); // Set TxQuadcal NCO frequency - status = ad9361_reg_write(dev, 0x00A3, 0x00); // Set TxQuadcal NCO frequency (Only update bits [7:6]) + status = ad9361_reg_write(dev, 0x00A0, 0x5F); // Set TxQuadcal NCO frequency + status = ad9361_reg_write(dev, 0x00A3, 0x80); // Set TxQuadcal NCO frequency (Only update bits [7:6]) status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold - status = ad9361_reg_write(dev, 0x00AA, 0x28); // Set Tx Quad Cal Gain Table index + status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count - status = ad9361_reg_write(dev, 0x00AE, 0x04); // Set Tx Quad Cal LPF Gain index incase Split table mode used + status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal @@ -1705,7 +1220,7 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ status |= ad9361_reg_read(dev, 0x0016, &value); mdelay(1);// Wait 1ms time_out_cnt++; - } while((value & 0x10) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); + } while((value & 0x10) != 0x00 && time_out_cnt <= TIMEOUT_TH); status = ad9361_reg_write(dev, 0x016A, 0x75); // Set Kexp Phase status = ad9361_reg_write(dev, 0x016B, 0x95); // Set Kexp Amplitude & Prevent Positive Gain Bit @@ -1736,11 +1251,5 @@ uint32_t ad9361_reg_config(struct ad9361_reg_dev *dev){ status = ad9361_reg_write(dev, 0x0158, 0x0D); // RSSI Mode Select status = ad9361_reg_write(dev, 0x015C, 0x67); // Power Measurement Duration -//************************************************************ -// Enable External LO & External VCO Buffer -//************************************************************ - status |= ad9361_reg_write(dev, 0x0005, 0x07); - status |= ad9361_reg_write(dev, 0x0057, 0x1C); - return status; } diff --git a/df_datalink_sp/src/dev_profile/ad9528_profile.c b/df_datalink_sp/src/dev_profile/ad9528_profile.c new file mode 100644 index 0000000..c2116c1 --- /dev/null +++ b/df_datalink_sp/src/dev_profile/ad9528_profile.c @@ -0,0 +1,134 @@ +#include "dev_profile.h" +#include "../config/app_config.h" +#include "../drivers/platform/xilinx_gpio.h" +#include "../drivers/axi_core/spi_engine/spi_engine.h" +#include "../drivers/frequency/ad9528/ad9528.h" + +static struct spi_engine_init_param spi_engine_param = { + .ref_clk_hz = AD9528_SPI_ENGINE_REF_CLK, + .type = SPI_ENGINE, + .spi_engine_baseaddr = AD9528_SPI_ENGINE_BASEADDR, + .cs_delay = AD9528_SPI_ENGINE_CS_DELAY, + .data_width = AD9528_SPI_ENGINE_DATA_WIDTH +}; + +static struct xil_gpio_init_param xil_gpio_param = { + .type = GPIO_PS, + .device_id = AD9528_GPIO_DEVICE_ID +}; + +static struct spi_init_param ad9528_spi_init = { + .device_id = AD9528_SPI_DEVICE_ID, + .max_speed_hz = AD9528_SPI_ENGINE_MAX_SPEED, + .mode = SPI_MODE_0, + .chip_select = AD9528_SPI_CS, + .platform_ops = &spi_eng_platform_ops, + .extra = &spi_engine_param +}; + +static struct gpio_init_param ad9528_gpio_resetb_init = { + .number = AD9528_RESETB, + .platform_ops = &xil_gpio_ops, + .extra = &xil_gpio_param +}; + +static struct gpio_init_param ad9528_gpio_sysref_req_init = { + .number = AD9528_SYSREF_REQ, + .platform_ops = &xil_gpio_ops, + .extra = &xil_gpio_param +}; + +static ad9528pll1Settings_t clockPll1Settings = { + .refA_Frequency_Hz = 50000000, + .refA_Divider = 1, + .refA_bufferCtrl = SINGLE_ENDED, + .refB_Frequency_Hz = 0, + .refB_Divider = 1, + .refB_bufferCtrl = DISABLED, + .vcxo_Frequency_Hz = 50000000, + .vcxoBufferCtrl = SINGLE_ENDED, + .nDivider = 1 +}; + +static ad9528pll2Settings_t clockPll2Settings = { + .rfDivider = 4, + .n2Divider = 20, + .totalNdiv = 80 +}; + +/******************************************************************* + * Output Distribution Settings + * 9369CE02A uses the following clock outputs + * OUT 1: FPGA REFCLK + * OUT 3: FPGA SYSREF + * OUT 12: DUT SYSREF + * OUT 13: DUT REFCLK + ******************************************************************* + */ +static ad9528outputSettings_t clockOutputSettings = { + .outPowerDown = 0xE001, + .outSource = { + AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, + AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, + AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV, AD9528_CHANNEL_DIV + }, + .outBufferCtrl = { + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0 + }, + .outAnalogDelay = { + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0 + }, + .outDigitalDelay = { + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0 + }, + .outChannelDiv = { + 5,25,25,5,5, + 5,5,8,5,5, + 5,5,10,5 + }, + .outFrequency_Hz = { + 200e6, 40e6, 40e6, 200e6, 200e6, + 200e6, 200e6, 125e6, 200e6, 200e6, + 200e6, 200e6, 100e6, 200e6 + } +}; + +static ad9528sysrefSettings_t clockSysrefSettings = { + .sysrefRequestMethod = PIN, + .sysrefSource = INTERNAL, + .sysrefPinEdgeMode = LEVEL_ACTIVE_HIGH, + .sysrefPinBufferMode = DISABLED, + .sysrefPatternMode = CONTINUOUS, + .sysrefNshotMode = FOUR_PULSES, + .sysrefDivide = 256 +}; + +static ad9528spiSettings_t clockSpiSettings = { + .chipSelectIndex = AD9528_SPI_CS, //chip select Index, not used + .writeBitPolarity = 0, //Write bit polarity + .longInstructionWord = 1, //16bit instruction word + .MSBFirst = 1, //MSB first + .CPHA = 0, //Clock phase + .CPOL = 0, //Clock polarity + .enSpiStreaming = 0, //uint8_t enSpiStreaming; + .autoIncAddrUp = 1, //uint8_t autoIncAddrUp; + .fourWireMode = 1 //uint8_t fourWireMode; +}; + +ad9528Init_t ad9528_default_init_param = { + /* SPI */ + .spi_init = &ad9528_spi_init, + .gpio_init_resetb = &ad9528_gpio_resetb_init, + .gpio_init_sysref_req = &ad9528_gpio_sysref_req_init, + .spiSettings = &clockSpiSettings, + .pll1Settings = &clockPll1Settings, + .pll2Settings = &clockPll2Settings, + .outputSettings = &clockOutputSettings, + .sysrefSettings = &clockSysrefSettings +}; diff --git a/df_datalink_sp/src/dev_profile/dev_profile.h b/df_datalink_sp/src/dev_profile/dev_profile.h index 3bb34a7..d4d28dd 100644 --- a/df_datalink_sp/src/dev_profile/dev_profile.h +++ b/df_datalink_sp/src/dev_profile/dev_profile.h @@ -6,6 +6,7 @@ #include "../drivers/rf-transceiver/ad9361/ad9361_api.h" #include "../drivers/rf-transceiver/ad9361_reg/ad9361_reg.h" #include "../drivers/frequency/hmc7044/hmc7044.h" +#include "../drivers/frequency/ad9528/ad9528.h" #include "../drivers/adc/ad9694/ad9694.h" #include "../config/app_config.h" @@ -17,6 +18,9 @@ extern struct global_timer_init_param globaltimer_init_param; // HMC7044 extern struct hmc7044_init_param hmc7044_default_init_param; +// AD9528 +extern ad9528Init_t ad9528_default_init_param; + // AD9361 extern AD9361_InitParam ad9361_default_init_param; extern AD9361_RXFIRConfig rx_fir_config; diff --git a/df_datalink_sp/src/dev_profile/hmc7044_profile.c b/df_datalink_sp/src/dev_profile/hmc7044_profile.c index 2d24d46..e1ad5a7 100644 --- a/df_datalink_sp/src/dev_profile/hmc7044_profile.c +++ b/df_datalink_sp/src/dev_profile/hmc7044_profile.c @@ -23,7 +23,7 @@ static struct spi_init_param hmc7044_spi_init_param = { .device_id = HMC7044_SPI_DEVICE_ID, .max_speed_hz = HMC7044_SPI_ENGINE_MAX_SPEED, .mode = SPI_MODE_4, - .chip_select = HMC7044_SPI_CS_HMC7044, + .chip_select = HMC7044_SPI_CS, .platform_ops = &spi_eng_platform_ops, .extra = &spi_engine_param }; @@ -42,9 +42,9 @@ struct hmc7044_chan_spec hmc7044_chan_spec[4] = { .dynamic_driver_enable = false, .output_control0_rb4_enable = true, .force_mute_enable = false, - .driver_mode = CML, + .driver_mode = HMC7044_CML, .driver_impedance = INTERNAL_100OHM_PER_PIN, - .out_mux_mode = CHANNEL_DIV + .out_mux_mode = HMC7044_CHANNEL_DIV }, /* FPGA_DAC_LOGIC_CLK */ { @@ -58,9 +58,9 @@ struct hmc7044_chan_spec hmc7044_chan_spec[4] = { .dynamic_driver_enable = false, .output_control0_rb4_enable = true, .force_mute_enable = false, - .driver_mode = CML, + .driver_mode = HMC7044_CML, .driver_impedance = INTERNAL_100OHM_PER_PIN, - .out_mux_mode = CHANNEL_DIV + .out_mux_mode = HMC7044_CHANNEL_DIV }, /* B_AD9361_XTAL */ { @@ -74,9 +74,9 @@ struct hmc7044_chan_spec hmc7044_chan_spec[4] = { .dynamic_driver_enable = false, .output_control0_rb4_enable = true, .force_mute_enable = false, - .driver_mode = CML, + .driver_mode = HMC7044_CML, .driver_impedance = INTERNAL_100OHM_PER_PIN, - .out_mux_mode = CHANNEL_DIV + .out_mux_mode = HMC7044_CHANNEL_DIV }, /* AD9361_RX_EXT_LO */ { @@ -90,9 +90,9 @@ struct hmc7044_chan_spec hmc7044_chan_spec[4] = { .dynamic_driver_enable = false, .output_control0_rb4_enable = true, .force_mute_enable = false, - .driver_mode = CML, + .driver_mode = HMC7044_CML, .driver_impedance = INTERNAL_100OHM_PER_PIN, - .out_mux_mode = CHANNEL_DIV + .out_mux_mode = HMC7044_CHANNEL_DIV }, }; diff --git a/df_datalink_sp/src/drivers/frequency/ad9528/ad9528.c b/df_datalink_sp/src/drivers/frequency/ad9528/ad9528.c new file mode 100644 index 0000000..7894fd6 --- /dev/null +++ b/df_datalink_sp/src/drivers/frequency/ad9528/ad9528.c @@ -0,0 +1,783 @@ +/** + * \file ad9528.c + * \brief Contains source code for configuring and initializing AD9528 clock device + */ + +/** +* \page Disclaimer Legal Disclaimer +* Copyright 2015-2017 Analog Devices Inc. +* Released under the AD9371 API license. +* +*/ + +#include +#include +#include "ad9528.h" +#include "../../../include/error.h" + +static uint32_t _desired_time_to_elapse_ms = 0; + +/** + * \brief Write data to a register + */ +int32_t AD9528_spiWriteByte(ad9528Device_t *device, uint16_t addr, + uint8_t data) +{ + uint8_t buf[3]; + int32_t status; + + buf[0] = (addr >> 8) & 0x7F; + buf[1] = addr & 0xFF; + buf[2] = data; + status = spi_write_and_read_3wire(device->spi_desc, + buf, NULL, 3, 0); + + return status; +} + +/** + * \brief Read data from a register + */ +int32_t AD9528_spiReadByte(ad9528Device_t *device, uint16_t addr, + uint8_t *readdata) +{ + uint8_t tx_buf[2]; + uint8_t rx_buf[1]; + int32_t status; + + tx_buf[0] = 0x80 | addr >> 8; + tx_buf[1] = addr & 0xFF; + + status = spi_write_and_read_3wire(device->spi_desc, + tx_buf, rx_buf, 2, 1); + + *readdata = rx_buf[0]; + + return status; +} + +/** + * \brief Modify a field of bits from a register + */ +int32_t AD9528_spiWriteField(ad9528Device_t *device, + uint16_t addr, uint8_t fieldVal, uint8_t mask, uint8_t startBit) +{ + int32_t errVal; + uint8_t readVal; + + errVal = AD9528_spiReadByte(device, addr, &readVal); + if (errVal < 0) + return errVal; + + readVal = (readVal & ~mask) | ((fieldVal << startBit) & mask); + + return AD9528_spiWriteByte(device, addr, readVal); +} + +/** + * \brief Set the desired timeout value + */ +int32_t AD9528_setTimeout_ms(uint32_t timeOut_ms) +{ + _desired_time_to_elapse_ms = timeOut_ms; + + return SUCCESS; +} + +/** + * \brief Verify if the desired time has elapsed + */ +int32_t AD9528_hasTimeoutExpired() +{ + udelay(1000); + + _desired_time_to_elapse_ms--; + if (_desired_time_to_elapse_ms > 0) + return SUCCESS; + + return FAILURE; +} + +/** + * \brief Performs a hard reset on the AD9528 DUT + * + * Dependencies + * - device->spiSettings->chipSelectIndex + * + * \param device is structure pointer to the AD9528 data structure containing settings + * \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail + */ +int32_t AD9528_resetDevice(ad9528Device_t *device) +{ + gpio_direction_output(device->gpio_resetb, 0); + mdelay(100); + gpio_direction_output(device->gpio_resetb, 1); + mdelay(100); + + AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x81); + mdelay(100); + AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, 0x00); + mdelay(100); + + return SUCCESS; +} + +/** + * \brief Sets the AD9528 device SPI settings (3wire/4wire, MSBFirst, etc). + * + * This function will use the settings in the device->spiSettings structure + * to set SPI stream mode, address auto increment direction, MSBFirst/LSBfirst, + * and 3wire/4wire mode. The AD9528 device always uses SPI MODE 0 (CPHA=0, CPOL=0). + * This function will update your device->spiSettings to set CHPA=0 and CPOL=0 and + * longInstructionWord =1 to use a 16bit instruction word. + * + * Dependencies + * - writes device->spiSettings->CPHA = 0 + * - writes device->spiSettings->CPOL = 0 + * - writes device->spiSettings->longInstructionWord = 1 + * + * - device->spiSettings->MSBFirst + * - device->spiSettings->enSpiStreaming + * - device->spiSettings->autoIncAddrUp + * - device->spiSettings->fourWireMode + * + * \param device is structure pointer to the AD9528 data structure containing settings + * + * \return Returns enum ADI_ERR, ADIERR_OK=pass, !ADIERR_OK=fail + */ +int32_t AD9528_setSpiSettings(ad9528Device_t *device) +{ + uint8_t spiReg = 0; + + device->spiSettings->CPHA = 0; + device->spiSettings->CPOL = 0; + device->spiSettings->longInstructionWord = 1; + + if (device->spiSettings->MSBFirst == 0) { + spiReg |= 0x42; /* SPI bit is 1=LSB first */ + } + + if (device->spiSettings->autoIncAddrUp > 0) { + spiReg |= 0x24; + } + + if (device->spiSettings->fourWireMode > 0) { + spiReg |= 0x18; + } + + AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_A, spiReg); + + if (device->spiSettings->enSpiStreaming > 0) { + /* Allow SPI streaming mode: SPI message ends when chip select deasserts */ + AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x00); + } else { + /* Force single instruction mode */ + AD9528_spiWriteByte(device, AD9528_ADDR_ADI_SPI_CONFIG_B, 0x80); + } + + return SUCCESS; +} + +/** + * \brief Helper function for ADI transceiver eval boards to init the AD9528 data structure + * + * This function inits the AD9528 device data structure with defaults that + * are known to work with the ADI AD9369 and AD9371 evaluation boards. NOTE: This function will + * modify the contents of the AD9528 device data structure. + * + * Dependencies + * - spi->chipSelectIndex + * - spi + * + * \param device Pointer to the AD9528 device data structure to initialize + * \param vcxoFrequency_Hz The VCXO frequency that is connected to the AD9528 + * \param refAFrequency_Hz The reference clock frequency being input into the AD9528 REFCLK A input + * \param outputDeviceClock_Hz Desired output clock frequency to the FPGA and transceiver device + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail +*/ +int32_t AD9528_initDeviceDataStruct(ad9528Device_t *device, + uint32_t vcxoFrequency_Hz, uint32_t refAFrequency_Hz, + uint32_t outputDeviceClock_Hz) +{ +// uint16_t chDiv; +// uint8_t i = 0; +// +// uint32_t pll1PfdFreq_Hz = 0; +// uint8_t pll1Ndiv = 0; +// uint8_t validPll1DivSetting = 0; +// uint8_t refAdiv = 1; +// +// +// uint8_t pll2RfDiv = 3; /* Valid values 3,4,5 */ +// uint16_t pll2Ndiv = 1; /* Valid values 1-256 */ +// uint32_t pll2InputFreq_Hz = 0; +// uint64_t pll2VcoFreq_Hz = 0; +// uint16_t pll2NdivStart = 0; +// uint8_t validPll2DivSetting = 0; +// uint64_t chDivU64 = 0; +// +// static const uint64_t PLL2_MIN_VCO_FREQ_HZ = 3450000000ULL; +// static const uint64_t PLL2_MAX_VCO_FREQ_HZ = 4025000000ULL; + +// struct spi_init_param spi_param; +// int32_t status; +// +// status = gpio_get(&device->gpio_resetb, CLK_RESETB); +// status |= gpio_get(&device->gpio_sysref_req, ADRV_SYSREF_REQ); +// +// spi_param.id = 0; +// spi_param.mode = SPI_MODE_0; +// spi_param.chip_select = CLK_CS; +// status |= spi_init(&device->spi_desc, &spi_param); +// +// if (status != SUCCESS) +// return FAILURE; + + /******************************************************************* + * PLL1 Settings + ******************************************************************* + */ + + /* find valid PLL1 Ndiv and REFA div */ +// for (pll1Ndiv = 1; pll1Ndiv < 20; pll1Ndiv++) { +// pll1PfdFreq_Hz = vcxoFrequency_Hz / pll1Ndiv; +// +// if ((pll1PfdFreq_Hz <= 110000000) && (pll1PfdFreq_Hz >= 1000000) && +// (pll1PfdFreq_Hz <= refAFrequency_Hz) && +// (refAFrequency_Hz % pll1PfdFreq_Hz == 0) +// ) { +// validPll1DivSetting = 1; +// refAdiv = refAFrequency_Hz / pll1PfdFreq_Hz ; +// break; +// } +// } +// +// if (validPll1DivSetting == 0) { +// return FAILURE; +// } + +// device->pll1Settings->nDivider = +// pll1Ndiv; //This init function always runs PLL1 at 30.72MHz Pfd rate +// device->pll1Settings->refA_bufferCtrl = +// DIFFERENTIAL; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +// device->pll1Settings->refA_Divider = refAdiv; +// device->pll1Settings->refA_Frequency_Hz = refAFrequency_Hz; +// device->pll1Settings->refB_bufferCtrl = +// DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +// device->pll1Settings->refB_Divider = 1; +// device->pll1Settings->refB_Frequency_Hz = 0; +// device->pll1Settings->vcxoBufferCtrl = +// NEG_SINGLE_ENDED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +// device->pll1Settings->vcxo_Frequency_Hz = vcxoFrequency_Hz; + + /******************************************************************* + * PLL2 Settings + ******************************************************************* + */ + + /******************************************************************* + * Output Distribution Settings + * 9369CE02A uses the following clock outputs + * OUT 1: FPGA REFCLK + * OUT 3: FPGA SYSREF + * OUT 12: DUT SYSREF + * OUT 13: DUT REFCLK + ******************************************************************* + */ + + /* PLL 2 input clock can be several different things. Currently hard coded by this init funciton to use + * PLL 1 output (VCXO Frequency) with no scaling + */ +// pll2InputFreq_Hz = device->pll1Settings->vcxo_Frequency_Hz; +// validPll2DivSetting = 0; + + /* Sweep PLL2 Divider settings to find something that has a valid integer divide (3,4,5)*/ +// for (pll2RfDiv = 3; pll2RfDiv <= 5; pll2RfDiv++) { +// +// pll2NdivStart = (PLL2_MIN_VCO_FREQ_HZ / pll2RfDiv / pll2InputFreq_Hz); +// /* find valid PLL2 Ndiv (1-256) */ +// for (pll2Ndiv = pll2NdivStart; pll2Ndiv <= 256; pll2Ndiv++) { +// pll2VcoFreq_Hz = (pll2InputFreq_Hz * pll2RfDiv * pll2Ndiv); +// +// if (pll2VcoFreq_Hz < PLL2_MIN_VCO_FREQ_HZ) { +// /* Continue to next PLL2 N div */ +// continue; +// } else if (pll2VcoFreq_Hz > PLL2_MAX_VCO_FREQ_HZ) { +// /* Break to next PLL2 RF div */ +// break; +// } +// +// if (((pll2VcoFreq_Hz / pll2RfDiv) % outputDeviceClock_Hz) == 0) { +// +// device->pll2Settings->rfDivider = pll2RfDiv; +// device->pll2Settings->n2Divider = pll2Ndiv; +// device->pll2Settings->totalNdiv = pll2RfDiv * pll2Ndiv; +// chDivU64 = ((pll2VcoFreq_Hz / pll2RfDiv) / outputDeviceClock_Hz); +// +// if ((chDivU64 < 1) || (chDivU64 > 256)) { +// return FAILURE; +// } else { +// chDiv = (uint16_t)(chDivU64); +// } +// +// validPll2DivSetting = 1; +// break; +// } +// } +// +// if (validPll2DivSetting == 1) { +// break; +// } +// } +// +// if (validPll2DivSetting == 0) { +// return FAILURE; +// } +// +// device->outputSettings->outPowerDown = (uint16_t)( +// ~0x318A); //enable outputs 13,12,8,7,3 and 1 +// +// for (i=0; i<14; i++) { +// device->outputSettings->outSource[i] = +// CHANNEL_DIV; //CHANNEL_DIV , PLL1_OUTPUT, SYSREF, INV_PLL1_OUTPUT +// device->outputSettings->outBufferCtrl[i] = LVDS; //LVDS, LVDS_BOOST, HSTL +// device->outputSettings->outChannelDiv[i] = chDiv; +// device->outputSettings->outFrequency_Hz[i] = outputDeviceClock_Hz; +// device->outputSettings->outAnalogDelay[i] = 0; +// device->outputSettings->outDigitalDelay[i] = 0; +// } +// +// +// device->outputSettings->outSource[3] = SYSREF; +// device->outputSettings->outSource[7] = SYSREF; +// device->outputSettings->outSource[12] = SYSREF; +// +// +// device->sysrefSettings->sysrefDivide = +// 512; //SYSREF frequency = VCXO / 2 / sysrefDivde +// device->sysrefSettings->sysrefNshotMode = +// ONE_PULSE; //ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5 +// device->sysrefSettings->sysrefPatternMode = +// CONTINUOUS; //NSHOT=0, CONTINUOUS=1, PRBS=2, STOP=3 +// device->sysrefSettings->sysrefPinBufferMode = +// DISABLED; //DISABLED = 0, SINGLE_ENDED, NEG_SINGLE_ENDED, DIFFERENTIAL +// device->sysrefSettings->sysrefPinEdgeMode = +// LEVEL_ACTIVE_HIGH; //LEVEL_ACTIVE_HIGH=0, LEVEL_ACTIVE_LOW=1, RISING_EDGE=2, FALLING_EDGE=3 +// device->sysrefSettings->sysrefRequestMethod = PIN; //SPI=0,PIN=1 +// device->sysrefSettings->sysrefSource = +// INTERNAL; //EXTERNAL=0, EXT_RESAMPLED=1, INTERNAL=2 + + return SUCCESS; +} + +int32_t AD9528_init(ad9528Device_t **device, const ad9528Init_t *init_device) +{ + int ret = SUCCESS; + ad9528Device_t *dev; + + dev = (ad9528Device_t *)malloc(sizeof(*dev)); + if (!dev) + return FAILURE; + + /* SPI */ + ret = spi_init(&dev->spi_desc, init_device->spi_init); + ret |= gpio_get(&dev->gpio_resetb, init_device->gpio_init_resetb); + ret |= gpio_get(&dev->gpio_sysref_req, init_device->gpio_init_sysref_req); + + gpio_direction_output(dev->gpio_resetb, 0); + gpio_direction_output(dev->gpio_sysref_req, 0); + + AD9528_resetDevice(dev); + + dev->spiSettings = init_device->spiSettings; + dev->pll1Settings = init_device->pll1Settings; + dev->pll2Settings = init_device->pll2Settings; + dev->outputSettings = init_device->outputSettings; + dev->sysrefSettings = init_device->sysrefSettings; + + *device = dev; + + return ret; +} + +/** + * \brief Initializes the AD9528 by writing all SPI registers + * + * Initializes the AD9528 for use with the AD9369 transceiver. Designed to work with + * a reference clock of 122.88MHz. Reference clock is expected to be 30.72MHz. + * The output clocks from the AD9528 can run at 122.88M, 153.6M, 184.32M, 245.76M, or 307.2M. + * Typical setup: REFA frequency = 30.72, VCXO = 122.88MHz + * SYNC(SYSREF) pulses output at rate of 120kHz + * + * Dependencies + * - All parameters in device structure + * + * \param device is structure pointer to AD9528 clock device structure + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + */ +int32_t AD9528_config(ad9528Device_t + *device) //writes all registers to desired values, leaves clock outputs off, SYSREF output disabled. +{ + uint8_t pll2_Adiv=0; + uint8_t pll2_Bdiv=0; + uint8_t reg108=0; + uint8_t reg109=0x4; + uint8_t i = 0; + uint8_t j = 0; + uint8_t reg508; + int32_t retval = SUCCESS; + + retval = AD9528_setSpiSettings(device); + if (retval != SUCCESS) { + return retval; + } + + /********************************************************************** + * Configure PLL1 + ********************************************************************** + */ + + AD9528_spiWriteByte(device, AD9528_ADDR_REF_A_DIVIDER_LSB, + device->pll1Settings->refA_Divider & 0xFF); //REF A div[7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_REF_A_DIVIDER_MSB, + (device->pll1Settings->refA_Divider >> 8) & 0x03); //REF A div[9:8] + AD9528_spiWriteByte(device, AD9528_ADDR_REF_B_DIVIDER_LSB, + device->pll1Settings->refB_Divider & 0xFF); //REF B div[7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_REF_B_DIVIDER_MSB, + (device->pll1Settings->refB_Divider >> 8) & 0x03); //REF B div[9:8] + AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_N_DIV_LSB, + device->pll1Settings->nDivider & 0xFF); //PLL1 N div[7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_N_DIV_MSB, + (device->pll1Settings->nDivider >> 8) & 0x03); //PLL1 N div[9:8] + AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_CHARGEPUMP, + 0x0A); //PLL1 Charge Pump control 1 + AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_CP_CTRL2, + 0x03); //PLL1 Charge Pump control 2 + + switch (device->pll1Settings->refA_bufferCtrl) { + case DISABLED: + reg108 &= ~0x28; + reg109 &= ~0x01; + break; //clear all REFA enable bits + case SINGLE_ENDED: + reg108 |= 0x08; + reg109 &= ~0x01; + break; //Set REFA receiver enable, clear REFA SE negative input enable + case NEG_SINGLE_ENDED: + reg108 |= 0x08; + reg108 &= ~0x10; + reg109 |= 0x01; + break; //Disable REFA diff receiver, enable REFA receiver and use negative REFA input + case DIFFERENTIAL: + reg108 |= 0x28; + reg109 &= ~0x01; + break; + default: + reg108 |= 0x08; + reg109 &= ~0x01; + break; //default to single ended case + } + switch (device->pll1Settings->refB_bufferCtrl) { + case DISABLED: + reg108 &= ~0x50; + reg109 &= ~0x02; + break; //clear all REFB enable bits + case SINGLE_ENDED: + reg108 |= 0x10; + reg109 &= ~0x02; + break; //Set REFB receiver enable, clear REFB SE negative input enable + case NEG_SINGLE_ENDED: + reg108 |= 0x10; + reg108 &= ~0x40; + reg109 |= 0x02; + break; //Disable REFB diff receiver, enable REFB receiver and use negative REFB input + case DIFFERENTIAL: + reg108 |= 0x50; + reg109 &= ~0x02; + break; + default: + reg108 |= 0x10; + reg109 &= ~0x02; + break; //default to single ended case + } + switch (device->pll1Settings->vcxoBufferCtrl) { + case DISABLED: + reg108 &= ~0x03; + reg108 |= 0x04; + break; //power down VCXO input + case SINGLE_ENDED: + reg108 &= ~0x07; + break; //Clear VCXO receiver power down, defaults to Single ended mode + case NEG_SINGLE_ENDED: + reg108 &= ~0x07; + reg108 |= 0x02; + break; //Clear VCXO power down, enable Negative single ended mode[1] + case DIFFERENTIAL: + reg108 &= ~0x07; + reg108 |= 0x01; + break; //Clear VCXO power down, enable differential input buffer[0] + default: + reg108 &= ~0x07; + break; //default to positive single ended case + } + + + AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS1, + reg108); //Input receiver settings (single ended or differential clock inputs) + AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS2, + reg109); //Input receiver settings + AD9528_spiWriteByte(device, AD9528_ADDR_INPUT_RECEIVERS3, + 0x0A); //Reference selection mode + AD9528_spiWriteByte(device, AD9528_ADDR_PLL1_FASTLOCK, + 0x00); //Disable Fast lock + + /********************************************************************** + * Configure PLL2 + ********************************************************************** + */ + pll2_Bdiv = device->pll2Settings->totalNdiv / 4; + pll2_Adiv = device->pll2Settings->totalNdiv % 4; + + if (pll2_Adiv > 3) { //A div valid range (0 to 3) + return FAILURE; + } + if (pll2_Bdiv < 3 || pll2_Bdiv > 63) { + return FAILURE; + } + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_CHARGEPUMP, + 0xE6); //PLL2 Charge Pump[7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_N_DIV, + ((pll2_Adiv & 0x3) << 6) | (pll2_Bdiv & 0x3F)); //PLL2 A and B divider + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_CTRL, 0x03); //PLL2 control + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_VCO_CTRL, 0x01); //Manual VCO CAL + + if (device->pll2Settings->rfDivider < 3 + || device->pll2Settings->rfDivider > 5) { + return FAILURE; + } + + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_VCO_DIV, + device->pll2Settings->rfDivider); //VCO divider + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_LF_CTRL1, + 0x3A); //PLL2 Loop filter [7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_LF_CTRL2, + 0x00); //PLL2 Loop filter [8] + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_RDIV, 0x01); //R divider + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_REPLICA_CHDIV, + (device->pll2Settings->totalNdiv / device->pll2Settings->rfDivider) + -1 ); //Replica channel divider: Ndivider = rfDivider * R divider + AD9528_spiWriteByte(device, AD9528_ADDR_PLL2_REPLICA_DIV_PHASE, + 0x00); //Replica Channel Divider phase + + /********************************************************************** + * Configure Output Distribution + ********************************************************************** + */ + for (i=0; i<14; i=i+1) { + AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CTRL1 + j, + ((device->outputSettings->outSource[i] & 0x7) << 5) | + (device->outputSettings->outAnalogDelay[i] & 0x1F)); + AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CTRL2 + j, + ((device->outputSettings->outBufferCtrl[i] & 0x3) << 6) | + (device->outputSettings->outDigitalDelay[i] & 0x3F)); + AD9528_spiWriteByte(device, AD9528_ADDR_CH_OUT0_CHDIV + j, + device->outputSettings->outChannelDiv[i]-1); + j = j+3; + } + + AD9528_spiWriteByte(device, AD9528_ADDR_OUTPUT_SYNC, 0x00); //Sync outputs + AD9528_spiWriteByte(device, AD9528_ADDR_MASK_SYNC1, 0x00); //Mask SYNC[7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_MASK_SYNC2, 0x00); //Mask SYNC[13:8] + AD9528_spiWriteByte(device, AD9528_ADDR_EN_OUTPUT_PATH_SEL1, + 0x00); //Bypass SYSREF resample [6:0], bit0:Enable VCXO to feed output distrubution + AD9528_spiWriteByte(device, AD9528_ADDR_EN_OUTPUT_PATH_SEL2, + 0x00); //Bypass SYSREF resample [13:7] + + /********************************************************************** + * Configure SYSREF operation + ********************************************************************** + */ + AD9528_spiWriteByte(device, AD9528_ADDR_SYSERF_DIV_LSB, + device->sysrefSettings->sysrefDivide & 0xFF); //SYSREF divider [7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_SYSERF_DIV_MSB, + (device->sysrefSettings->sysrefDivide >> 8) & 0xFF); //SYSREF divider [7:0] + + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL3, + ((device->sysrefSettings->sysrefRequestMethod & 0x1) << 7) | + ((device->sysrefSettings->sysrefPinEdgeMode & 0x3) << 5) ); + + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL4, + ((device->sysrefSettings->sysrefSource & 0x03) << 6) | + ((device->sysrefSettings->sysrefPatternMode & 0x3) << 4 ) | + ((device->sysrefSettings->sysrefNshotMode & 0x7) << 1) ); + + if(device->sysrefSettings->sysrefPinBufferMode == DISABLED) { + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5, + 0x04); //power down input buffer for external SYSREF + } else if(device->sysrefSettings->sysrefPinBufferMode == SINGLE_ENDED) { + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5, + 0x00); //enable positive singled ended input + } else if(device->sysrefSettings->sysrefPinBufferMode == NEG_SINGLE_ENDED) { + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5, + 0x02); //enable negative singled ended input + } else if(device->sysrefSettings->sysrefPinBufferMode == DIFFERENTIAL) { + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5, + 0x01); //enable differential input buffer + } else { + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL5, + 0x04); //power down input buffer for external SYSREF + } + + /********************************************************************** + * Power down control + ********************************************************************** + */ + + if (device->pll1Settings->bypassPll1 > 0) { + AD9528_spiWriteByte(device, AD9528_ADDR_POWERDOWN_CTRL, + 0x14);// power up PLL2 and output distribution, power down PLL1 + } else { + AD9528_spiWriteByte(device, AD9528_ADDR_POWERDOWN_CTRL, + 0x10);// power up PLL1, PLL2 and output distribution + } + + AD9528_spiWriteByte(device, AD9528_ADDR_CH_POWERDOWN1, + device->outputSettings->outPowerDown & 0xFF); //power down out[7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_CH_POWERDOWN2, + ((device->outputSettings->outPowerDown >> 8) & 0x3F)); //power down out[13:8] + AD9528_spiWriteByte(device, AD9528_ADDR_LDO_ENABLES1, + 0xFF); //LDO enable per output channel [7:0] + AD9528_spiWriteByte(device, AD9528_ADDR_LDO_ENABLES2, + 0xFF); //LDO enable per output channel [15:8] + AD9528_spiWriteByte(device, AD9528_ADDR_STATUS0_CTRL, + 0x07); //STATUS 0 outputs REFA present + AD9528_spiWriteByte(device, AD9528_ADDR_STATUS1_CTRL, + 0x01); //STATUS 1 outputs PLL1 and PLL2 locked + AD9528_spiWriteByte(device, AD9528_ADDR_STATUS_OE, + 0x0C);// Make Status0 and Status1 outputs after reset. + + AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE, + 0x01); //IO update to make all these settings valid in the 9528 + + AD9528_setTimeout_ms(1000); + + do { + AD9528_spiReadByte(device, AD9528_ADDR_STATUS_READBACK0, ®508); + if(AD9528_hasTimeoutExpired() > 0) { + return FAILURE; + } + } while((reg508 & 0x26) != 0x26); + + return SUCCESS; +} + + +/// Send a SPI message to request a SYSREF pulse or continuous SYSREF from the AD9528. +/*******************************************************************************//** + * Requests a SYSREF from the AD9528. It will use whatever settings for SYSREF + * that are current configured in the AD9528. This could be a single pulse, + * multiple pulses, or continuous pulses. + * Dependencies + * - device->spiSettings + * - device->sysrefSettings->sysrefPatternMode + * + * \param device is structure pointer to AD9528 clock device structure + * \param enableSYSREF If NSHOT SYSREF mode, this parameter is ignored. If PRBS/CONTINUOUS SYSREF mode, 1= enable SYSREF, 0= disable SYSREF. + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + ***********************************************************************************/ +int32_t AD9528_requestSysref(ad9528Device_t *device, uint8_t enableSYSREF) +{ + uint8_t _enableSYSREF=0; + + if (device->sysrefSettings->sysrefPatternMode == NSHOT || enableSYSREF > 0) { + _enableSYSREF = 1; + } else { + _enableSYSREF = 0; + } + + AD9528_spiWriteField(device, AD9528_ADDR_SYSREF_CTRL4, _enableSYSREF, 0x01, + 0x00); //Set SPI SYSREF request bit + AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE, + 0x01); //IO update to make all these settings valid in the 9528 + + return SUCCESS; +} + +/// Allow changing the 9528 SYSREF frequency and pattern mode(CONTINUOUS, PRBS vs NSHOT mode) +/*******************************************************************************//** + * NOTE: this function will update the device structure with the parameter values passed + * into this function. The device->sysrefSettings->sysrefPatternMode, device->sysrefSettings->sysrefNshotMode, + * and device->sysrefSettings->sysrefDivide values will be updated in the device structure. + * + * Dependencies + * - device->spiSettings + * + * \param device is structure pointer to AD9528 clock device structure + * \param divideFromPll1Out Sets the SYSREF pulse frequency. SYSREF frequency = PLL1_VCXO frequency/divideFromPll1Out + * \param sysrefPatternMode Valid settings: NSHOT, CONTINUOUS, PRBS, STOP + * \param nShotPulses Valid settings: ONE_PULSE=0, TWO_PULSES=2, FOUR_PULSES=3, SIX_PULSES=4, EIGHT_PULSES=5 + * + * \return Returns enum ADI_ERR, 0=pass, >0 = fail + ***********************************************************************************/ +int32_t AD9528_setupSYSREF(ad9528Device_t *device, + uint16_t divideFromPll1Out, sysrefPatternMode_t sysrefPatternMode, + sysrefNshotMode_t nShotPulses) +{ + uint8_t reg403=0; + + device->sysrefSettings->sysrefPatternMode = sysrefPatternMode; + device->sysrefSettings->sysrefNshotMode = nShotPulses; + device->sysrefSettings->sysrefDivide = divideFromPll1Out >> + 1; //SYSREF frequency is (PLL1)VCXO frequency / 2 / device->sysrefSettings->sysrefDivide + + AD9528_spiReadByte(device, AD9528_ADDR_SYSREF_CTRL4, ®403); + + reg403 = reg403 & ~0x01; //clear bit 0 to stop a continuous sysref if it is on. + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL4, reg403); + + reg403 = reg403 & ~0x3E; //clear bits for pattern mode and Nshot mode bitfields + reg403 = reg403 | ((sysrefPatternMode & 0x3) << 4) | ((nShotPulses & 0x7) << 1); + AD9528_spiWriteByte(device, AD9528_ADDR_SYSREF_CTRL4, + reg403); //update internal sysref pattern mode and Nshot mode (number of pulses) + + //SYSREF request bit x403[0] is left 0. The next call to AD9528_requestSysref will start the SYSREF + AD9528_spiWriteByte(device, AD9528_ADDR_IO_UPDATE, + 0x01); //IO update to make all these settings valid in the 9528 + + + return SUCCESS; +} + +int32_t AD9528_sysrefReq(ad9528Device_t *device, + ad9528SysrefReqMode_t mode) +{ + if (mode == SYSREF_CONT_ON) + gpio_direction_output(device->gpio_sysref_req, 1); + else if (mode == SYSREF_CONT_OFF) + gpio_direction_output(device->gpio_sysref_req, 0); + else if (mode == SYSREF_PULSE) { + gpio_direction_output(device->gpio_sysref_req, 1); + mdelay(1); + gpio_direction_output(device->gpio_sysref_req, 0); + } else + return FAILURE; + + return SUCCESS; +} + +/** + * \brief Free the allocated resources + */ +int32_t AD9528_remove(ad9528Device_t *device) +{ + int32_t status; + + status = gpio_remove(device->gpio_resetb); + status |= gpio_remove(device->gpio_sysref_req); + status |= spi_remove(device->spi_desc); + + return SUCCESS; +} diff --git a/df_datalink_sp/src/drivers/frequency/ad9528/ad9528.h b/df_datalink_sp/src/drivers/frequency/ad9528/ad9528.h new file mode 100644 index 0000000..9f89655 --- /dev/null +++ b/df_datalink_sp/src/drivers/frequency/ad9528/ad9528.h @@ -0,0 +1,245 @@ +/** + * \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 diff --git a/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.h b/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.h index a178975..0e4b5aa 100644 --- a/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.h +++ b/df_datalink_sp/src/drivers/frequency/hmc7044/hmc7044.h @@ -75,10 +75,10 @@ typedef enum // 0x0148, 0x0152) typedef enum { - CML = 0, - LVPECL = 1, - LVDS = 2, - CMOS = 3 + HMC7044_CML = 0, + HMC7044_LVPECL = 1, + HMC7044_LVDS = 2, + HMC7044_CMOS = 3 } hmc7044DriverMode_t; // Enum to select the GPIx functionality. (0x0046, 0x0047, 0x0048, 0x0049) @@ -154,7 +154,7 @@ typedef enum // 0x0101, 0x010B, 0x0115, 0x011F, 0x0129, 0x0133, 0x013D, 0x0147, 0x0151 typedef enum { - CHANNEL_DIV = 0, + HMC7044_CHANNEL_DIV = 0, ANALOG_DELAY = 1, OTHER_CHANNEL = 2, VCO_CLOCK = 3 diff --git a/df_datalink_sp/src/hwconfig.c b/df_datalink_sp/src/hwconfig.c index 52169aa..3c350a6 100644 --- a/df_datalink_sp/src/hwconfig.c +++ b/df_datalink_sp/src/hwconfig.c @@ -34,7 +34,7 @@ /************************** Function Prototypes ******************************/ /*********************** Driver Instance Definitions **************************/ -static struct hmc7044_dev *hmc7044_inst = NULL; +ad9528Device_t *ad9528_inst = NULL; static struct ad9361_reg_dev *ad9361_1_reg_inst = NULL; static struct ad9361_reg_dev *ad9361_2_reg_inst = NULL; // static struct ad9361_rf_phy *ad9361_phy; @@ -62,12 +62,17 @@ int32_t Hardware_Init(void) } /**********************************************************/ - /****************** HMC7044 Configuration *****************/ + /****************** AD9528 Configuration ******************/ /**********************************************************/ - Status = hmc7044_init(&hmc7044_inst, &hmc7044_default_init_param); - if (Status != SUCCESS) - { - DBG_ERROR("hmc7044_init() error: %" PRId32 "\n", Status); + Status = AD9528_init(&ad9528_inst, &ad9528_default_init_param); + if (Status != SUCCESS) { + DBG_ERROR("AD9528_init() error: %" PRId32 "\n", Status); + return FAILURE; + } + + Status = AD9528_config(ad9528_inst); + if (Status != SUCCESS) { + DBG_ERROR("AD9528_config() error: %" PRId32 "\n", Status); return FAILURE; } @@ -110,110 +115,6 @@ int32_t Hardware_Init(void) // Status = ad9361_reg_read(ad9361_1_reg_inst, 0x0002, &rd_back); // Status = ad9361_reg_read(ad9361_2_reg_inst, 0x0002, &rd_back); - /**********************************************************/ - /******* AD9361 Baseband Multichip Synchronization ********/ - /**********************************************************/ - XGpioPs_SetDirectionPin(&Gpio, AD9361_SYNC, AD9361_GPIO_OUTPUT); - XGpioPs_SetDirectionPin(&Gpio, AD9361_RX_FIFO_RST, AD9361_GPIO_OUTPUT); - - // SYNC BBPLL and DIGITAL SAMPLING CLOCKS - ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0D); // MCS RF Enable; MCS BBPLL Enable; MCS BB Enable - ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0D); - ad9361_reg_write(ad9361_1_reg_inst, 0x0047, 0x80); // MCS refclk Scale Enable - ad9361_reg_write(ad9361_2_reg_inst, 0x0047, 0x80); - XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0); - mdelay(20); - XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input a rising-edge pulse to the SYNC_IN pin - mdelay(500); - XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0); - mdelay(2000); - ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0B); // MCS RF Enable; MCS Digital CLK Enable ; MCS BB Enable - ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0B); - XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input another rising-edge pulse to the SYNC_IN pin - mdelay(500); - XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0); - ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x08); // clear MCS bits - ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x08); - - XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0); - mdelay(20); - XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 1); - mdelay(20); - XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0); - - /**********************************************************/ - /********* AD9361 Multichip Rx Phase Calibration **********/ - /**********************************************************/ - XGpioPs_SetDirectionPin(&Gpio, AD9361_TX_SWITCH, AD9361_GPIO_OUTPUT); - XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_START, AD9361_GPIO_OUTPUT); - XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_DONE, AD9361_GPIO_INPUT); - XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_START, AD9361_GPIO_OUTPUT); - XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_DONE, AD9361_GPIO_INPUT); - - // switch to lower frequency - Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_126); - XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 1); - mdelay(20); - - // switch rx channel - Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x30); - Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x30); - - // enable dual ad9361 tx channels - Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xE4); // Setup Tx Digital Filters/ Channels - - // switch ad9361 tx channel - Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x70); // Select Rx input pin(A,B,C)/ Tx out pin (A,B) - mdelay(20); - - // begin to calibrate the 1st ad9361 - XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0); - XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 1); - mdelay(1); - XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0); - - // read calibration status - int32_t time_out_cnt = 0; - do - { - mdelay(1); // Wait 1ms - time_out_cnt++; - } while (((XGpioPs_ReadPin(&Gpio, AD9361_1_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH)); - - if (time_out_cnt == AD9361_TIMEOUT_TH) - { - return FAILURE; - } - - // begin to calibrate the 2nd ad9361 - XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 1); - mdelay(1); - XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 0); - - // read calibration status - time_out_cnt = 0; - do - { - mdelay(1); // Wait 1ms - time_out_cnt++; - } while (((XGpioPs_ReadPin(&Gpio, AD9361_2_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH)); - - if (time_out_cnt == AD9361_TIMEOUT_TH) - { - return FAILURE; - } - - // enable single ad9361 tx channels - Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xA4); // Setup Tx Digital Filters/ Channels - - // switch ad9361 tx & rx channel - Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x03); - Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x03); - - // switch to higher frequency - Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_4125); - XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 0); - Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0109, 0x00); // Rx Gain Status = ad9361_reg_write(ad9361_1_reg_inst, 0x010C, 0x00); // Rx Gain Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0109, 0x00); // Rx Gain @@ -224,176 +125,6 @@ int32_t Hardware_Init(void) return SUCCESS; } -/*****************************************************************************/ -/** - * @brief Hardware_SwitchFreq - * - * @param devSysMonitor_UpdateHardwareStatus(newHwState); - * @param freq - * - * @return None. - * - ******************************************************************************/ -int32_t Hardware_SwitchFreq(struct ad9361_reg_dev *dev, ad9361TxFreq freq) -{ - int32_t status = 0; - uint8_t value = 0; - int32_t time_out_cnt = 0; - - switch (freq) - { - case TX_FREQ_125: - { - //************************************************************ - // Setup Tx Frequency-Dependent Syntheisizer Registers - //************************************************************ - status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0] - status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] - status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] - status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0] - status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0] - status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0] - status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] - status = ad9361_reg_write(dev, 0x027B, 0x94); // Set Synth Loop Filter charge pump current (Icp) - status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1 - status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3 - status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3 - - //************************************************************ - // Write Tx Frequency Words - //************************************************************ - status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0] - status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8] - status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16] - status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8] - status = ad9361_reg_write(dev, 0x0271, 0xA0); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) - status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting - - //************************************************************ - // Tx Quadrature Calibration Settings - //************************************************************ - status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency - status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6]) - status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable - status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count - status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp - status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold - status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold - status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index - status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count - status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used - - status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration - status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal - - break; - } - case TX_FREQ_126: - { - //************************************************************ - // Setup Tx Frequency-Dependent Syntheisizer Registers - //************************************************************ - status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0] - status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] - status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] - status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0] - status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0] - status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0] - status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] - status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp) - status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1 - status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3 - status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3 - - //************************************************************ - // Write Tx Frequency Words - //************************************************************ - status = ad9361_reg_write(dev, 0x0273, 0x06); // Write Tx Synth Fractional Freq Word[7:0] - status = ad9361_reg_write(dev, 0x0274, 0xD7); // Write Tx Synth Fractional Freq Word[15:8] - status = ad9361_reg_write(dev, 0x0275, 0x23); // Write Tx Synth Fractional Freq Word[22:16] - status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8] - status = ad9361_reg_write(dev, 0x0271, 0xA1); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) - status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting - - //************************************************************ - // Tx Quadrature Calibration Settings - //************************************************************ - status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency - status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6]) - status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable - status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count - status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp - status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold - status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold - status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index - status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count - status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used - - status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration - status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal - - break; - } - case TX_FREQ_4125: - { - //************************************************************ - // Setup Tx Frequency-Dependent Syntheisizer Registers - //************************************************************ - status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0] - status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0] - status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0] - status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0] - status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0] - status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0] - status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0] - status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp) - status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1 - status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3 - status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3 - - //************************************************************ - // Write Rx Frequency Words - //************************************************************ - status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0] - status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8] - status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16] - status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8] - status = ad9361_reg_write(dev, 0x0271, 0xA5); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal) - status = ad9361_reg_write(dev, 0x0005, 0x07); // Set LO divider setting - - //************************************************************ - // Tx Quadrature Calibration Settings - //************************************************************ - status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency - status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6]) - status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable - status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count - status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp - status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold - status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold - status = ad9361_reg_write(dev, 0x00AA, 0x28); // Set Tx Quad Cal Gain Table index - status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count - status = ad9361_reg_write(dev, 0x00AE, 0x04); // Set Tx Quad Cal LPF Gain index incase Split table mode used - - status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration - status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal - - break; - } - - // Wait for cal to complete (Done when 0x016[4]==0) - time_out_cnt = 0; - do - { - status |= ad9361_reg_read(dev, 0x0016, &value); - mdelay(1); // Wait 1ms - time_out_cnt++; - } while ((value & 0x10) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH); - } - - return status; -} - // @ Get AD9361 - 1 temperature (Celsius Degree) /** * Read corresponding register to get AD9361 - 1 current temperature. @@ -453,22 +184,22 @@ uint8_t Hardware_GetAD9361LockStatus(void) return ret; } -// @ Determine HMC7044 lock state +// @ Determine AD9528 lock state /** * Read corresponding register to determine clock lock state. */ -uint8_t Hardware_GetHMC7044LockStatus(void) +uint8_t Hardware_GetAD9528LockStatus(void) { uint8_t ret = 0; uint8_t regVal; // pll1 - hmc7044_read(hmc7044_inst, 0x007C, ®Val); // [D5] is lock indicator - ret |= ((regVal & 0xE0) != 0x00) ? CLK_SP_PLL0_LOCK : 0; - - // pll2 - hmc7044_read(hmc7044_inst, 0x007D, ®Val); // [D0] is lock indicator + AD9528_spiReadByte(ad9528_inst, AD9528_ADDR_STATUS_READBACK0, ®Val); // [D0] is lock indicator ret |= ((regVal & 0x01) == 0x01) ? CLK_SP_PLL1_LOCK : 0; + // pll2 + AD9528_spiReadByte(ad9528_inst, AD9528_ADDR_STATUS_READBACK0, ®Val); // [D1] is lock indicator + ret |= ((regVal & 0x02) == 0x02) ? CLK_SP_PLL2_LOCK : 0; + return ret; -} \ No newline at end of file +} diff --git a/df_datalink_sp/src/hwconfig.h b/df_datalink_sp/src/hwconfig.h index e54c291..077c0db 100644 --- a/df_datalink_sp/src/hwconfig.h +++ b/df_datalink_sp/src/hwconfig.h @@ -24,10 +24,9 @@ /************************** Function Prototypes ******************************/ int32_t Hardware_Init(void); -int32_t Hardware_SwitchFreq(struct ad9361_reg_dev *dev, ad9361TxFreq freq); int8_t Hardware_GetAD9361Temp_1(void); int8_t Hardware_GetAD9361Temp_2(void); uint8_t Hardware_GetAD9361LockStatus(void); -uint8_t Hardware_GetHMC7044LockStatus(void); +uint8_t Hardware_GetAD9528LockStatus(void); #endif // HWCONFIG_H_ diff --git a/df_datalink_sp/src/main.c b/df_datalink_sp/src/main.c index 91e148b..7b52f7a 100644 --- a/df_datalink_sp/src/main.c +++ b/df_datalink_sp/src/main.c @@ -98,7 +98,7 @@ static PHY_CONFIG phyConfig = { .txBramId = PHY_TXBUFF_BRAM_DEVICE_ID, .rxBramId = PHY_RXBUFF_BRAM_DEVICE_ID, .hwXadcId = PHY_HW_XADC_DEVICE_ID, - .get_clk_state = Hardware_GetHMC7044LockStatus, + .get_clk_state = Hardware_GetAD9528LockStatus, .get_ad_lock_state = Hardware_GetAD9361LockStatus, .get_ad0_temp = Hardware_GetAD9361Temp_1, .get_ad1_temp = Hardware_GetAD9361Temp_2 diff --git a/df_datalink_sp/src/networking/phy_layer/phy_layer.c b/df_datalink_sp/src/networking/phy_layer/phy_layer.c index 57d2a15..eadb67c 100644 --- a/df_datalink_sp/src/networking/phy_layer/phy_layer.c +++ b/df_datalink_sp/src/networking/phy_layer/phy_layer.c @@ -1116,7 +1116,7 @@ void Phy_RefreshHwSate(PHY_INST *instPtr) ? INT8_MAX : ((evalData < TEMPERATURE_MIN) ? INT8_MIN : (int8_t)round(evalData / TEMPERATURE_LSB)); instPtr->hwSate.isSpOk = (instPtr->hwSate.spFpgaVolt == (VOLT_PS_OK | VOLT_PSAUX_OK | VOLT_DDR_OK | VOLT_PL_OK | VOLT_PLAUX_OK | VOLT_BRAM_OK)) - && (instPtr->hwSate.spClkState == (CLK_SP_PLL0_LOCK | CLK_SP_PLL1_LOCK)) + && (instPtr->hwSate.spClkState == (CLK_SP_PLL1_LOCK | CLK_SP_PLL2_LOCK)) && (instPtr->hwSate.spAdLockState == (CLK_AD0_BBPLL_LOCK | CLK_AD0_RFPLL_LOCK | CLK_AD1_BBPLL_LOCK | CLK_AD1_RFPLL_LOCK)); #else instPtr->hwSate.isSpOk = true; @@ -1142,8 +1142,8 @@ void Phy_RefreshHwSate(PHY_INST *instPtr) // [2] - PLLA lock status // [4] - PLLB lock status instPtr->hwSate.antPll = ((rawData & ANT_RF_STATUS_BBLOCK_MASK) == ANT_RF_STATUS_BBLOCK_OK) ? CLK_ANT_BBPLL_LOCK : 0x00; - instPtr->hwSate.antPll |= ((rawData & ANT_RF_STATUS_PLLA_MASK) == ANT_RF_STATUS_PLLA_OK) ? CLK_ANT_RFPLL0_LOCK : 0x00; - instPtr->hwSate.antPll |= ((rawData & ANT_RF_STATUS_PLLB_MASK) == ANT_RF_STATUS_PLLB_OK) ? CLK_ANT_RFPLL1_LOCK : 0x00; + instPtr->hwSate.antPll |= ((rawData & ANT_RF_STATUS_PLLA_MASK) == ANT_RF_STATUS_PLLA_OK) ? CLK_ANT_RFPLL1_LOCK : 0x00; + instPtr->hwSate.antPll |= ((rawData & ANT_RF_STATUS_PLLB_MASK) == ANT_RF_STATUS_PLLB_OK) ? CLK_ANT_RFPLL2_LOCK : 0x00; /*** MGCs ***/ rawData = PhyRead(instPtr, ANT_RF_MGC); @@ -1159,7 +1159,7 @@ void Phy_RefreshHwSate(PHY_INST *instPtr) // Determin if antenna is ok. instPtr->hwSate.isAntOk = (instPtr->hwSate.antVolt == (VOLT_ANT_PROC_OK | VOLT_ANT_RF_OK | VOLT_ANT_NIL_OK | ANT_STATE_OK)) - && (instPtr->hwSate.antPll == (CLK_ANT_BBPLL_LOCK | CLK_ANT_RFPLL0_LOCK | CLK_ANT_RFPLL1_LOCK)); + && (instPtr->hwSate.antPll == (CLK_ANT_BBPLL_LOCK | CLK_ANT_RFPLL1_LOCK | CLK_ANT_RFPLL2_LOCK)); instPtr->hwSate.phyId = instPtr->phyCofig.devId; @@ -1390,4 +1390,4 @@ void Phy_GetLastReceivedSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotSta /** @} PhysicalLayer_Receive_Estimations*/ -/** @} PhysicalLayer*/ \ No newline at end of file +/** @} PhysicalLayer*/ diff --git a/df_datalink_sp/src/system_monitor.h b/df_datalink_sp/src/system_monitor.h index 6dffefc..e74ca3d 100644 --- a/df_datalink_sp/src/system_monitor.h +++ b/df_datalink_sp/src/system_monitor.h @@ -61,8 +61,8 @@ #define IS_PLAUX_VALID(x) ((x) <= 2.0 && (x) >= 1.6) #define IS_BRAM_VALID(x) ((x) <= 1.1 && (x) >= 0.9) -#define CLK_SP_PLL0_LOCK BIT(0) -#define CLK_SP_PLL1_LOCK BIT(2) +#define CLK_SP_PLL1_LOCK BIT(0) +#define CLK_SP_PLL2_LOCK BIT(2) #define CLK_AD0_BBPLL_LOCK BIT(0) #define CLK_AD0_RFPLL_LOCK BIT(2) @@ -70,8 +70,8 @@ #define CLK_AD1_RFPLL_LOCK BIT(6) #define CLK_ANT_BBPLL_LOCK BIT(0) -#define CLK_ANT_RFPLL0_LOCK BIT(2) -#define CLK_ANT_RFPLL1_LOCK BIT(4) +#define CLK_ANT_RFPLL1_LOCK BIT(2) +#define CLK_ANT_RFPLL2_LOCK BIT(4) #define TEMPERATURE_LSB 1.0 // Celsius degree #define TEMPERATURE_MAX 127.0 // Celsius degree @@ -238,4 +238,4 @@ void SysMonitor_GetHardwareStatus(HWSTATE *state); #endif //__SYSTEM_MONITOR_H_ -/** @} */ \ No newline at end of file +/** @} */