#include "lmx2594.h" #include const uint32_t lmx2594_rst[] = { 0x002516, 0x002514 }; uint32_t lmx2594regs[LMX_COUNT] = { 0x700000, 0x6F0000, 0x6E0000, 0x6D0000, 0x6C0000, 0x6B0000, 0x6A0000, 0x690021, 0x680000, 0x670000, 0x660000, 0x650011, 0x640000, 0x630000, 0x620000, 0x610888, 0x600000, 0x5F0000, 0x5E0000, 0x5D0000, 0x5C0000, 0x5B0000, 0x5A0000, 0x590000, 0x580000, 0x570000, 0x560000, 0x550000, 0x540000, 0x530000, 0x520000, 0x510000, 0x500000, 0x4F0000, 0x4E016F, 0x4D0000, 0x4C000C, 0x4B0800, 0x4A0000, 0x49003F, 0x480001, 0x470081, 0x46C350, 0x450000, 0x4403E8, 0x430000, 0x4201F4, 0x410000, 0x401388, 0x3F0000, 0x3E0322, 0x3D00A8, 0x3C03E8, 0x3B0001, 0x3A9001, 0x390020, 0x380000, 0x370000, 0x360000, 0x350000, 0x340820, 0x330080, 0x320000, 0x314180, 0x300300, 0x2F0300, 0x2E07FC, 0x2DC8DF, 0x2C1FA0, 0x2B0000, 0x2A0000, 0x290000, 0x280000, 0x2703E8, 0x260000, 0x250104, 0x240032, 0x230004, 0x220000, 0x211E21, 0x200393, 0x1F43EC, 0x1E318C, 0x1D318C, 0x1C0488, 0x1B0002, 0x1A0DB0, 0x190C2B, 0x18071A, 0x17007C, 0x160001, 0x150401, 0x14F848, 0x1327B7, 0x120064, 0x11012C, 0x100080, 0x0F064F, 0x0E1E40, 0x0D4000, 0x0C5001, 0x0B0018, 0x0A10D8, 0x090604, 0x082000, 0x0740B2, 0x06C802, 0x0500C8, 0x041243, 0x030642, 0x020500, 0x010808, 0x00251C }; void auto_cal(void *bar1) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_R0_FCAL); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | LMX2594_R0_FCAL_EN; uint32_t *ptr_header = bar1+LMX_BASE_ADDR; *ptr_header = ((0 << 23) | (DeviceIdLmx2594 << 18) | (0x1 << 1) | 1); uint32_t *ptr = bar1 + LMX_BASE_ADDR; *ptr = lmx2594regs[112-FCAL_ADDR]; } void lmx2594_init(void *bar1) { // Header for LMX Reset uint32_t *ptr = bar1 + LMX_BASE_ADDR; *ptr = LMX2594_RST_HEADER; // Reset Data for (int m = 0; m < (sizeof(lmx2594_rst))/4; m++) { *ptr = lmx2594_rst[m]; } // Header for init data *ptr = InitLMX2594Header; // Init data for (int i = 0; i < LMX_COUNT; i++) { *ptr = lmx2594regs[i]; } usleep(10); auto_cal(bar1); } /*-------------------------LMX2594 Frequency Set-------------------------*/ int lmx_freq_set_main_band_int_mode(void *bar1, double lmx_freq, double f_pd) { double N_div; printf("f_pd before = %f\n",f_pd); N_div = lmx_freq / f_pd; uint32_t N = (uint32_t) N_div; if (lmx_freq <= 12500e6) { if (N < 28){ N= 28; } } else if (lmx_freq > 12500e6) { if (N <32) { N = 32; } }; int vco_core; double f_coremin; double f_coremax; int c_core_min; int c_core_max; int a_core_min; int a_core_max; uint16_t vco_cap_ctrl_strt; uint16_t vco_daciset_strt; // Partial assist for the calibration //Determine a VCO core and other parameters if (lmx_freq >= 7500e6 && lmx_freq <= 8600e6) { vco_core = 1; f_coremin = 7500e6; f_coremax = 8600e6; c_core_min = 164; c_core_max = 12; a_core_min = 299; a_core_max = 240; } else if (lmx_freq > 8600e6 && lmx_freq < 9800e6) { vco_core = 2; f_coremin = 8600e6; f_coremax = 9800e6; c_core_min = 165; c_core_max = 16; a_core_min = 356; a_core_max = 247; } else if (lmx_freq >= 9800e6 && lmx_freq <= 10800e6) { vco_core = 3; f_coremin = 9800e6; f_coremax = 10800e6; c_core_min = 158; c_core_max = 19; a_core_min = 324; a_core_max = 224; } else if (lmx_freq > 10800e6 && lmx_freq <= 12000e6) { vco_core = 4; f_coremin = 10800e6; f_coremax = 12000e6; c_core_min = 140; c_core_max = 0; a_core_min = 383; a_core_max = 244; } else if (lmx_freq > 12000e6 && lmx_freq <= 12900e6) { vco_core = 5; f_coremin = 12000e6; f_coremax = 12900e6; c_core_min = 183; c_core_max = 36; a_core_min = 205; a_core_max = 146; } else if (lmx_freq > 12900e6 && lmx_freq <= 13900e6) { vco_core = 6; f_coremin = 12900e6; f_coremax = 13900e6; c_core_min = 155; c_core_max = 6; a_core_min = 242; a_core_max = 163; } else if (lmx_freq > 13900e6 && lmx_freq <= 15000e6) { vco_core = 7; f_coremin = 13900e6; f_coremax = 15000e6; c_core_min = 175; c_core_max = 19; a_core_min = 323; a_core_max = 244; }; if (lmx_freq >=11900e6 && lmx_freq <=12100e6) { vco_daciset_strt = 300; vco_core = 4; vco_cap_ctrl_strt = 1; } vco_cap_ctrl_strt = round(c_core_min - (c_core_min - c_core_max) * (lmx_freq - f_coremin) / (f_coremax - f_coremin)); vco_daciset_strt = round(a_core_min + (a_core_min - a_core_max) * (lmx_freq - f_coremin) / (f_coremax - f_coremin)); //Set the VCO_CORE lmx2594regs[112 - VCO_SEL] = lmx2594regs[112 - VCO_SEL] & (~BITM_LMX2594_R20_VCO_SEL); lmx2594regs[112 - VCO_SEL] = lmx2594regs[112 - VCO_SEL] | (vco_core << BITP_LMX2594_R20_VCO_SEL); // Set the VCO_CAP_CTRL lmx2594regs[112 - CAP_CTRL_START] = lmx2594regs[112 - CAP_CTRL_START] & (~BITM_LMX2594_R78_VCO_CAP_CTRL_START); lmx2594regs[112 - CAP_CTRL_START] = lmx2594regs[112 - CAP_CTRL_START] | (vco_cap_ctrl_strt << BITP_LMX2594_R78_VCO_CAP_CTRL_START); // Set the VCO_DACISET lmx2594regs[112 - VCO_DACISET] = lmx2594regs[112 - VCO_DACISET] & (~BITM_LMX2594_R17_VCO_DACISET); lmx2594regs[112 - VCO_DACISET] = lmx2594regs[112 - VCO_DACISET] | (vco_daciset_strt << BITP_LMX2594_R17_VCO_DACISET); // Set the PF_DLY_SEL if (lmx_freq <= 12500e6) { lmx2594regs[112-PFD_DLY_SEL] = lmx2594regs[112-PFD_DLY_SEL] & (~BITM_LMX2594_R37_PFD_DLY_SEL); lmx2594regs[112-PFD_DLY_SEL] = lmx2594regs[112-PFD_DLY_SEL] | (0x1 << BITP_LMX2594_R37_PFD_DLY_SEL); } else if (lmx_freq > 12500e6) { lmx2594regs[112-PFD_DLY_SEL] = lmx2594regs[112-PFD_DLY_SEL] & (~BITM_LMX2594_R37_PFD_DLY_SEL); lmx2594regs[112-PFD_DLY_SEL] = lmx2594regs[112-PFD_DLY_SEL] | (0x2 << BITP_LMX2594_R37_PFD_DLY_SEL); }; int cal_clk_div; //SET the FCAL_HPFD_ADJ if (f_pd <= 100e6) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_RO_FCAL_HPFD_ADJ); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | ENUM_LMX2594_R0_FCAL_HPFD_ADJ_LESS100MHZ; } else if (f_pd > 100e6 && f_pd <= 150e6) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_RO_FCAL_HPFD_ADJ); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | ENUM_LMX2594_R0_FCAL_HPFD_ADJ_100_150MHZ; } else if (f_pd > 150e6 && f_pd <= 200e6) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_RO_FCAL_HPFD_ADJ); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | ENUM_LMX2594_R0_FCAL_HPFD_ADJ_150_200MHZ; } else if (f_pd > 200e6) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_RO_FCAL_HPFD_ADJ); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | ENUM_LMX2594_R0_FCAL_HPFD_ADJ_MORE200MHZ; } // SET the CAL_CLK_DIV value if (f_pd <= 200e6 ) { lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] & (~BITM_LMX2594_R1_CAL_CLK_DIV); lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] | ENUM_LMX2594_R1_CAL_CLK_DIV1; cal_clk_div = 0; } else if (f_pd > 200e6 && f_pd <= 400e6) { lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] & (~BITM_LMX2594_R1_CAL_CLK_DIV); lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] | ENUM_LMX2594_R1_CAL_CLK_DIV2; cal_clk_div = 1; } else if (f_pd > 400e6 && f_pd < 800e6) { lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] & (~BITM_LMX2594_R1_CAL_CLK_DIV); lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] | ENUM_LMX2594_R1_CAL_CLK_DIV4; cal_clk_div = 2; }; //Calculate the ACAL_CMP_DLY double Fsmclk = f_pd/(pow(2,cal_clk_div)); uint8_t acal_cmp_dly = (uint8_t) ((uint64_t)round((Fsmclk)/10e6)); //Set the ACAL_CMP_DLY value lmx2594regs[112-R4_ADDR] = lmx2594regs[112-R4_ADDR] &(~BITM_LMX2594_R4_ACAL_CMP_DLY); lmx2594regs[112-R4_ADDR] = lmx2594regs[112-R4_ADDR] | (acal_cmp_dly << BITP_LMX2594_R4_ACAL_CMP_DLY); // SET the N_DIV lmx2594regs[112-PLL_N_S] = lmx2594regs[112-PLL_N_S] &(~0xFFFF); lmx2594regs[112-PLL_N_S] = lmx2594regs[112-PLL_N_S] | (N >> 16); //CLear the lower 16 bits of the register lmx2594regs[112-PLL_N_M] = lmx2594regs[112-PLL_N_M] & (~0xFFFF); // Next 16 bits of the register lmx2594regs[112-PLL_N_M] = lmx2594regs[112-PLL_N_M] | (N & 0xFFFF); // Clear the SEG1_EN bit lmx2594regs[112-CHDIV_DIV2] = lmx2594regs[112 - CHDIV_DIV2] & (~BITM_LMX2594_R31_CHDIV_DIV2); // Set the OUTA_MUX to channel divider R45[12:11]; 0 - Channel divider, 1 - VCO; // Removed unnecessary commented-out LMX_HEADER definition lmx2594regs[112 - OUTA_MUX] = lmx2594regs[112 - OUTA_MUX] | ENUM_LMX2594_R45_OUTA_MUX_VCO; // Program the FCAL_EN bit lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_R0_FCAL); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | (LMX2594_R0_FCAL_EN); uint32_t lmx_change_freq_regs[] = { lmx2594regs[112 - VCO_SEL], lmx2594regs[112 - CAP_CTRL_START], lmx2594regs[112 - VCO_DACISET], lmx2594regs[112-PFD_DLY_SEL], lmx2594regs[112-R4_ADDR], lmx2594regs[112-R1_ADDR], lmx2594regs[112-CHDIV_DIV2], lmx2594regs[112-PLL_N_S], lmx2594regs[112-PLL_N_M], lmx2594regs[112 - OUTA_MUX], lmx2594regs[112-FCAL_ADDR] }; // Create a header for the LMX2594 with the appropriate number of words // uint32_t LMX_HEADER = ((0 << 23) | (DeviceIdLmx2594 << 18) | ((sizeof(lmx_change_freq_regs)/4) << 1) | 1); // Create a header for the LMX2594 with the appropriate number of words MOSI 4 uint32_t LMX_HEADER = ((0x1<< 23) | ((sizeof(lmx_change_freq_regs) / 4) << BITP_LMX2594_4MOSI_HEADER) | 1); uint32_t *ptr = bar1 + LMX_BASE_ADDR; *ptr = LMX_HEADER; for (int i = 0; i < sizeof(lmx_change_freq_regs)/4; i++) { uint32_t *data_ptr = bar1 + LMX_BASE_ADDR; *data_ptr = lmx_change_freq_regs[i]; } return 0; } int lmx_freq_set_out_of_band_int_mode(void *bar1, double lmx_freq, double f_pd) { double f_vco = 2 * lmx_freq; int chan_div = 2; uint8_t ch_div_reg = 0; // 2 double vco_div = 7.5e9 / lmx_freq; int vco_core; double f_coremin; double f_coremax; int c_core_min; int c_core_max; int a_core_min; int a_core_max; uint16_t vco_cap_ctrl_strt; uint16_t vco_daciset_strt; // minimum N_div value is 28 and Vco frequency can't be less than 7.5 GHz if (f_vco < 7.5e9) { if (vco_div > 2 && vco_div <= 4) { chan_div = 4; // 4 f_vco = lmx_freq * chan_div; } else if (vco_div > 4 && vco_div <= 6) { chan_div = 6; // 6 f_vco = lmx_freq * chan_div; } else if (vco_div > 6 && vco_div <= 8) { chan_div = 8; // 8 f_vco = lmx_freq * chan_div; } else if (vco_div > 8 && vco_div <= 12) { chan_div = 12; // 12 f_vco = lmx_freq * chan_div; } else if (vco_div > 12 && vco_div <= 16) { chan_div = 16; // 16 f_vco = lmx_freq * chan_div; } else if (vco_div > 16 && vco_div <= 24) { chan_div = 24; // 24 f_vco = lmx_freq * chan_div; } else if (vco_div > 24 && vco_div <= 32) { chan_div = 32; // 32 f_vco = lmx_freq * chan_div; } else if (vco_div > 32 && vco_div <= 48) { chan_div = 48; // 48 f_vco = lmx_freq * chan_div; } else if (vco_div > 48 && vco_div <= 64) { chan_div = 64; // 64 f_vco = lmx_freq * chan_div; } else if (vco_div > 64 && vco_div <= 72) { chan_div = 72; // 72 f_vco = lmx_freq * chan_div; } else if (vco_div > 72 && vco_div <= 96) { chan_div = 96; // 96 f_vco = lmx_freq * chan_div; } else if (vco_div > 96 && vco_div <= 128) { chan_div = 128; // 128 f_vco = lmx_freq * chan_div; } else if (vco_div > 128 && vco_div <= 192) { chan_div = 192; // 192 f_vco = lmx_freq * chan_div; } else if (vco_div > 192 && vco_div <= 256) { chan_div = 256; // 256 f_vco = lmx_freq * chan_div; } else if (vco_div > 256 && vco_div <= 384) { chan_div = 384; // 384 f_vco = lmx_freq * chan_div; } else if (vco_div > 384 && vco_div <= 512) { chan_div = 512; // 512 f_vco = lmx_freq * chan_div; } else if (vco_div > 512 && vco_div <= 768) { chan_div = 768; // 768 f_vco = lmx_freq * chan_div; } switch (chan_div) { case 2: ch_div_reg = 0; break; case 4: ch_div_reg = 1; break; case 6: ch_div_reg = 2; break; case 8: ch_div_reg = 3; break; case 12: ch_div_reg = 4; break; case 16: ch_div_reg = 5; break; case 24: ch_div_reg = 6; break; case 32: ch_div_reg = 7; break; case 48: ch_div_reg = 8; break; case 64: ch_div_reg = 9; break; case 72: ch_div_reg = 10; break; case 96: ch_div_reg = 11; break; case 128: ch_div_reg = 12; break; case 192: ch_div_reg = 13; break; case 256: ch_div_reg = 14; break; case 384: ch_div_reg = 15; break; case 512: ch_div_reg = 16; break; case 768: ch_div_reg = 17; break; } } else { ch_div_reg = 0; f_vco = lmx_freq * 2; } double N_div = f_vco / f_pd; uint32_t N = (uint32_t) N_div; if (f_vco <= 12500e6) { if (N < 28){ N= 28; }; } else if (f_vco > 12500e6) { if (N <32) { N = 32; } }; // Partial assist for the calibration //Determine a VCO core and other parameters if (f_vco >= 7500e6 && f_vco <= 8600e6) { vco_core = 1; f_coremin = 7500e6; f_coremax = 8600e6; c_core_min = 164; c_core_max = 12; a_core_min = 299; a_core_max = 240; } else if (f_vco > 8600e6 && f_vco < 9800e6) { vco_core = 2; f_coremin = 8600e6; f_coremax = 9800e6; c_core_min = 165; c_core_max = 16; a_core_min = 356; a_core_max = 247; } else if (f_vco >= 9800e6 && f_vco <= 10800e6) { vco_core = 3; f_coremin = 9800e6; f_coremax = 10800e6; c_core_min = 158; c_core_max = 19; a_core_min = 324; a_core_max = 224; } else if (f_vco > 10800e6 && f_vco <= 12000e6) { vco_core = 4; f_coremin = 10800e6; f_coremax = 12000e6; c_core_min = 140; c_core_max = 0; a_core_min = 383; a_core_max = 244; } else if (f_vco > 12000e6 && f_vco <= 12900e6) { vco_core = 5; f_coremin = 12000e6; f_coremax = 12900e6; c_core_min = 183; c_core_max = 36; a_core_min = 205; a_core_max = 146; } else if (f_vco > 12900e6 && f_vco <= 13900e6) { vco_core = 6; f_coremin = 12900e6; f_coremax = 13900e6; c_core_min = 155; c_core_max = 6; a_core_min = 242; a_core_max = 163; } else if (f_vco > 13900e6 && f_vco <= 15000e6) { vco_core = 7; f_coremin = 13900e6; f_coremax = 15000e6; c_core_min = 175; c_core_max = 19; a_core_min = 323; a_core_max = 244; }; vco_cap_ctrl_strt = round(c_core_min - (c_core_min - c_core_max) * (f_vco - f_coremin) / (f_coremax - f_coremin)); vco_daciset_strt = round(a_core_min + (a_core_min - a_core_max) * (f_vco - f_coremin) / (f_coremax - f_coremin)); if (f_vco >=11900e6 && f_vco <=12100e6) { vco_daciset_strt = 300; vco_core = 4; vco_cap_ctrl_strt = 1; } // Calibration assist //Set the VCO_CORE lmx2594regs[112 - VCO_SEL] = lmx2594regs[112 - VCO_SEL] & (~BITM_LMX2594_R20_VCO_SEL); lmx2594regs[112 - VCO_SEL] = lmx2594regs[112 - VCO_SEL] | (vco_core << BITP_LMX2594_R20_VCO_SEL); // Set the VCO_CAP_CTRL_START lmx2594regs[112 - CAP_CTRL_START] = lmx2594regs[112 - CAP_CTRL_START] & (~BITM_LMX2594_R78_VCO_CAP_CTRL_START); lmx2594regs[112 - CAP_CTRL_START] = lmx2594regs[112 - CAP_CTRL_START] | (vco_cap_ctrl_strt << BITP_LMX2594_R78_VCO_CAP_CTRL_START); // Set the VCO_DACISET lmx2594regs[112 - VCO_DACISET] = lmx2594regs[112 - VCO_DACISET] & (~BITM_LMX2594_R17_VCO_DACISET); lmx2594regs[112 - VCO_DACISET] = lmx2594regs[112 - VCO_DACISET] | (vco_daciset_strt << BITP_LMX2594_R17_VCO_DACISET); // Set the PFD_DLY_SEL to appropriate value if (f_vco <= 12500e6) { lmx2594regs[112-PFD_DLY_SEL] = lmx2594regs[112-PFD_DLY_SEL] & (~BITM_LMX2594_R37_PFD_DLY_SEL); lmx2594regs[112-PFD_DLY_SEL] = lmx2594regs[112-PFD_DLY_SEL] | (0x1 << BITP_LMX2594_R37_PFD_DLY_SEL); // printf("PFD_DLY_SEL = %d\n", 1); } else if (f_vco > 12500e6) { lmx2594regs[112-PFD_DLY_SEL] = lmx2594regs[112-PFD_DLY_SEL] & (~BITM_LMX2594_R37_PFD_DLY_SEL); lmx2594regs[112-PFD_DLY_SEL] = lmx2594regs[112-PFD_DLY_SEL] | (0x2 << BITP_LMX2594_R37_PFD_DLY_SEL); // printf("PFD_DLY_SEL = %d\n", 2); } if (f_pd <= 100e6) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_RO_FCAL_HPFD_ADJ); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | ENUM_LMX2594_R0_FCAL_HPFD_ADJ_LESS100MHZ; } else if (f_pd > 100e6 && f_pd <= 150e6) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_RO_FCAL_HPFD_ADJ); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | ENUM_LMX2594_R0_FCAL_HPFD_ADJ_100_150MHZ; } else if (f_pd > 150e6 && f_pd <= 200e6) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_RO_FCAL_HPFD_ADJ); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | ENUM_LMX2594_R0_FCAL_HPFD_ADJ_150_200MHZ; } else if (f_pd > 200e6) { lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] & (~BITM_LMX2594_RO_FCAL_HPFD_ADJ); lmx2594regs[112-FCAL_ADDR] = lmx2594regs[112-FCAL_ADDR] | ENUM_LMX2594_R0_FCAL_HPFD_ADJ_MORE200MHZ; }; // SET the CAL_CLK_DIV value int cal_clk_div; if (f_pd <= 200e6 ) { lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] & (~BITM_LMX2594_R1_CAL_CLK_DIV); lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] | ENUM_LMX2594_R1_CAL_CLK_DIV1; cal_clk_div =0; } else if (f_pd > 200e6 && f_pd <= 400e6) { lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] & (~BITM_LMX2594_R1_CAL_CLK_DIV); lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] | ENUM_LMX2594_R1_CAL_CLK_DIV2; cal_clk_div =1; } else if (f_pd > 400e6 && f_pd < 800e6) { lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] & (~BITM_LMX2594_R1_CAL_CLK_DIV); lmx2594regs[112-R1_ADDR] = lmx2594regs[112-R1_ADDR] | ENUM_LMX2594_R1_CAL_CLK_DIV4; cal_clk_div = 2; }; //Calculate the ACAL_CMP_DLY double Fsmclk = f_pd/(pow(2,cal_clk_div)); uint8_t acal_cmp_dly = (uint8_t) ((uint64_t)round((Fsmclk)/10e6));; //Set the ACAL_CMP_DLY value lmx2594regs[112-R4_ADDR] = lmx2594regs[112-R4_ADDR] &(~BITM_LMX2594_R4_ACAL_CMP_DLY); lmx2594regs[112-R4_ADDR] = lmx2594regs[112-R4_ADDR] | (acal_cmp_dly << BITP_LMX2594_R4_ACAL_CMP_DLY); // Set the N value lmx2594regs[112-PLL_N_S] = lmx2594regs[112-PLL_N_S] &(~0xFFFF); lmx2594regs[112-PLL_N_S] = lmx2594regs[112-PLL_N_S] | (N >> 16); //CLear the lower 16 bits of the register lmx2594regs[112-PLL_N_M] = lmx2594regs[112-PLL_N_M] & (~0xFFFF); // Next 16 bits of the register lmx2594regs[112-PLL_N_M] = lmx2594regs[112-PLL_N_M] | (N & 0xFFFF); // Program the CHDIV value lmx2594regs[112 - CHDIV] = lmx2594regs[112 - CHDIV] & (~BITM_LMX2594_R75_CHDIV); // Set the CHDIV value with the starting position BITP_LMX2594_R75_CHDIV lmx2594regs[112 - CHDIV] = lmx2594regs[112 - CHDIV] | (ch_div_reg << BITP_LMX2594_R75_CHDIV); // If the ch_div > 2 then set the SEG1_EN bit if (chan_div > 2) { lmx2594regs[112 - CHDIV_DIV2] = lmx2594regs[112 - CHDIV_DIV2] & (~BITM_LMX2594_R31_CHDIV_DIV2); lmx2594regs[112 - CHDIV_DIV2] = lmx2594regs[112 - CHDIV_DIV2] | (ENUM_LMX2594_R31_CHDIV_DIV2_EN); } else { lmx2594regs[112-CHDIV_DIV2] = lmx2594regs[112 - CHDIV_DIV2] & (~BITM_LMX2594_R31_CHDIV_DIV2); } // Set the OUTA_MUX to channel divider R45[12:11]; 0 - Channel divider, 1 - VCO; lmx2594regs[112 - OUTA_MUX] = lmx2594regs[112 - OUTA_MUX] & (~BITM_LMX2594_R45_OUTA_MUX); lmx2594regs[112 - OUTA_MUX] = lmx2594regs[112 - OUTA_MUX] | ENUM_LMX2594_R45_OUTA_MUX_CH_DIV; // Program the FCAL_EN bit lmx2594regs[112 - FCAL_ADDR] = lmx2594regs[112 - FCAL_ADDR] & (~LMX2594_R0_FCAL_EN); lmx2594regs[112 - FCAL_ADDR] = lmx2594regs[112 - FCAL_ADDR] | (LMX2594_R0_FCAL_EN); uint32_t lmx_change_freq_regs []={ lmx2594regs[112 - VCO_SEL], lmx2594regs[112 - CAP_CTRL_START], lmx2594regs[112 - VCO_DACISET], lmx2594regs[112-PFD_DLY_SEL], lmx2594regs[112-R4_ADDR], lmx2594regs[112-R1_ADDR], lmx2594regs[112 - PLL_N_S], lmx2594regs[112 - PLL_N_M], lmx2594regs[112 - CHDIV], lmx2594regs[112 - CHDIV_DIV2], lmx2594regs[112 - OUTA_MUX], lmx2594regs[112 - FCAL_ADDR] }; // Create a header for the LMX2594 with the appropriate number of words MOSI 4 uint32_t LMX_HEADER = ((0x1<< 23) | ((sizeof(lmx_change_freq_regs) / 4) << BITP_LMX2594_4MOSI_HEADER) | 1); uint32_t *ptr = bar1 + LMX_BASE_ADDR; *ptr = LMX_HEADER; // Send the data for (int i = 0; i < sizeof(lmx_change_freq_regs) / 4; i++) { uint32_t *data_ptr = bar1 + LMX_BASE_ADDR; *data_ptr = lmx_change_freq_regs[i]; } // char filename[100]; // sprintf(filename, "%f.txt", lmx_freq); // FILE * f = fopen(filename, "w"); // for (int i = 0; i < sizeof(lmx2594regs) / 4; i++) { // fprintf(f, "0x%08X\n", lmx2594regs[i]); // } // fclose(f); // printf("N_div = %f\n", N_div); // printf("f_vco = %f\n", f_vco); // printf("N = %d\n", N); // printf("chan_div = %d\n", chan_div); // printf("chan_div_reg = %d\n", ch_div_reg); return 0; } double lmx_lower_bond_set (double freq, double f_pd) { double f_max2870 = 4e9; double lmx_req_freq = f_max2870-freq; // 4 GHz - freq return lmx_req_freq; } double lmx_get_freq(double freq) { if (freq < 100e3 || freq> 45e9) { printf("Frequency range is 100 kHz to 45 GHz\n"); return -1; } if (freq >= 100e3 && freq <= 1000e6) { double f_max2870 = 4e9; double lmx_freq = f_max2870-freq; // 4 GHz - freq return lmx_freq; } else if (freq > 1000e6 && freq <= 15e9) { return freq; } else if (freq > 15e9 && freq <=27e9) { return freq/2; } else if (freq > 27e9 && freq <= 45e9) { return freq/4; } } int lmx_freq_set(void *bar1, double lmx_freq,double f_pd) { // Set the 4 Mosi mode usleep(1); uint32_t cfg_reg = get_cfg_reg(); SET_REGISTER_PARAM(cfg_reg, CFG_REG_SPI_MODE_BITM, CFG_REG_SPI_MODE_BITP, CFG_REG_SPI_MODE_4MOSI); uint32_t *spi_mode = bar1 +CFG_REG_ADDR; *spi_mode = cfg_reg; usleep(1); SET_REGISTER_PARAM(cfg_reg, CFG_REG_RST_FOR_FPGA_BITM, CFG_REG_RST_FOR_FPGA_BITP, CFG_REG_RST_FOR_FPGA_ON); *spi_mode = cfg_reg; usleep(1); SET_REGISTER_PARAM(cfg_reg, CFG_REG_RST_FOR_FPGA_BITM, CFG_REG_RST_FOR_FPGA_BITP, CFG_REG_RST_FOR_FPGA_OFF); *spi_mode = cfg_reg; // if the frequency is in the main band - 7.5 GHz to 15 GHz if (lmx_freq >= 7.5e9 && lmx_freq <= 15e9) { // lmx_freq_set_main_band(bar1, freq, f_pd); lmx_freq_set_main_band_int_mode(bar1, lmx_freq, f_pd); } else if (lmx_freq < 7.5e9) { // lmx_freq_set_out_of_band(bar1, freq, f_pd); lmx_freq_set_out_of_band_int_mode(bar1, lmx_freq, f_pd); } // Return the 1 MOSI mode usleep(1); SET_REGISTER_PARAM(cfg_reg,CFG_REG_SPI_MODE_BITM,CFG_REG_SPI_MODE_BITP, CFG_REG_SPI_MODE_1MOSI); *spi_mode = cfg_reg; usleep(1); set_cfg_reg(cfg_reg); return 0; } uint32_t lmx_ld_status(void *bar1) { uint32_t *read_ptr = (uint32_t *)(bar1 + LMX_LD_STATUS_ADDR); uint32_t read_value = *read_ptr; return read_value; }