#include "stm32f0xx.h" #include "main.h" #include "lmx2595.h" uint16_t debug_outen=0; _LMX2595_REG lmx; static LMX_MAP_T sLMX_MAP_T = { //sck { GPIOA, LL_GPIO_PIN_5, }, //sdi { GPIOA, LL_GPIO_PIN_7, }, //csb { GPIOA, LL_GPIO_PIN_4, }, //ldo { GPIOA, LL_GPIO_PIN_6, } }; unsigned char gLmxLdSta = 0x00; static void DELAY_Nop(uint32_t num) { while(num--) { __NOP(); } } void Lmx_CSB_SET(void) { LL_GPIO_SetOutputPin(sLMX_MAP_T.CSB.gpio, sLMX_MAP_T.CSB.gpio_pin); } void Lmx_CSB_RESET(void) { LL_GPIO_ResetOutputPin(sLMX_MAP_T.CSB.gpio, sLMX_MAP_T.CSB.gpio_pin); } void Lmx_SCK_SET(void) { LL_GPIO_SetOutputPin(sLMX_MAP_T.SCK.gpio, sLMX_MAP_T.SCK.gpio_pin); } void Lmx_SCK_RESET(void) { LL_GPIO_ResetOutputPin(sLMX_MAP_T.SCK.gpio, sLMX_MAP_T.SCK.gpio_pin); } void Lmx_SDI_SET(void) { LL_GPIO_SetOutputPin(sLMX_MAP_T.SDI.gpio, sLMX_MAP_T.SDI.gpio_pin); } void Lmx_SDI_RESET(void) { LL_GPIO_ResetOutputPin(sLMX_MAP_T.SDI.gpio, sLMX_MAP_T.SDI.gpio_pin); } uint8_t spi_8bit(uint8_t dat) { uint8_t rCtrlSpiCodeB; uint8_t i; uint8_t B_Miso = 0x00; rCtrlSpiCodeB = dat; for(i=0;i<8;i++) { B_Miso = (B_Miso<<0x01); if((rCtrlSpiCodeB&0x80) == 0x00) { Lmx_SDI_RESET(); } else { Lmx_SDI_SET(); } Lmx_SCK_RESET(); DELAY_Nop(100); Lmx_SCK_SET(); DELAY_Nop(100); //上升沿后微小延时,读取MISO数据// B_Miso = (LL_GPIO_ReadInputPort(sLMX_MAP_T.LDO.gpio) & (0x01<< 6)); Lmx_SCK_RESET(); rCtrlSpiCodeB = (rCtrlSpiCodeB<<1); } return B_Miso; } uint16_t spi_16bit(uint16_t dat) { uint16_t rCtrlSpiCodeW; uint8_t i; uint16_t W_Miso = 0x00; rCtrlSpiCodeW = dat; for(i=0;i<16;i++) { W_Miso = (W_Miso<<0x0001); if((rCtrlSpiCodeW&0x8000) == 0x0000) { Lmx_SDI_RESET(); } else { Lmx_SDI_SET(); } Lmx_SCK_RESET(); DELAY_Nop(100); Lmx_SCK_SET(); //上升沿后微小延时,读取MISO数据// W_Miso = (W_Miso | (LL_GPIO_ReadInputPort(sLMX_MAP_T.LDO.gpio)& (0x01<<6))); DELAY_Nop(100); Lmx_SCK_RESET(); rCtrlSpiCodeW = (rCtrlSpiCodeW<<1); } return W_Miso; } //对器件进行读操作,输入为寄存器地址,返回读出的数据// uint16_t lmxRead(uint8_t regadr) { uint16_t rddat; regadr = regadr|0x80; //将寄存器地址最高位置1,确保为读操作// Lmx_CSB_RESET(); //片选信号拉低// DELAY_Nop(50); Lmx_SCK_RESET(); DELAY_Nop(50); spi_8bit(regadr); //送出地址// rddat=spi_16bit(0); //送出16位无效数据,用于回读寄存器数据// DELAY_Nop(50); Lmx_CSB_SET(); //片选失效// return rddat; } void LmxWrite(uint8_t regadr,uint16_t dat) { printf("write addr 0x%02x 0x%04x\r\n",regadr,dat); regadr=regadr&0x7f; //将寄存器地址最高位置0,确保为写操作// Lmx_CSB_RESET(); //片选信号拉低// DELAY_Nop(50); Lmx_SCK_RESET(); DELAY_Nop(50); spi_8bit(regadr); //送出地址// spi_16bit(dat); //送出数据// DELAY_Nop(50); Lmx_CSB_SET(); //片选失效// } void LmxPortReset(void) { Lmx_CSB_SET(); //片选失效// Lmx_SCK_RESET(); Lmx_SDI_RESET(); } void Lmx_PortIntit(void) { LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = LL_GPIO_PIN_2; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_3; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_4; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_5; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_6; GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_7; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); LmxPortReset(); } void SetLmxParameter(void) { lmx.LMX_R70.All= 0x0000; lmx.LMX_R69.All= 0x0000; lmx.LMX_R68.All= 0x0000; lmx.LMX_R64.All= 0x0000; lmx.LMX_R62.All= 0x0000; lmx.LMX_R61.All= 0x0000; lmx.LMX_R59.All= 0x0000; lmx.LMX_R48.All= 0x03FC; lmx.LMX_R47.All= 0x00D4; lmx.LMX_R46.All= 0x1421; lmx.LMX_R45.All= 0x0000; lmx.LMX_R44.All= 0x0000; lmx.LMX_R43.All= 0x0000; lmx.LMX_R42.All= 0x0000; lmx.LMX_R41.All= 0x0001; lmx.LMX_R40.All= 0x0000; lmx.LMX_R39.All= 0x8104; lmx.LMX_R38.All= 0x0960; lmx.LMX_R37.All= 0x5000; lmx.LMX_R36.All= 0x0C44; lmx.LMX_R35.All= 0x119B; lmx.LMX_R34.All= 0xC3EA; lmx.LMX_R33.All= 0x0000; lmx.LMX_R32.All= 0x0000; lmx.LMX_R31.All= 0x0601; lmx.LMX_R30.All= 0x0134; lmx.LMX_R29.All= 0x0000; lmx.LMX_R28.All= 0x0000; lmx.LMX_R25.All= 0x0000; lmx.LMX_R24.All= 0x0000; lmx.LMX_R23.All= 0x0000; lmx.LMX_R22.All= 0x0000; lmx.LMX_R20.All= 0x0000; lmx.LMX_R19.All= 0x0000; lmx.LMX_R14.All= 0x039C; lmx.LMX_R13.All= 0x4003; lmx.LMX_R12.All= 0x7001; lmx.LMX_R11.All= 0x0148; lmx.LMX_R10.All= 0x10D8; lmx.LMX_R9.All =0x0800; lmx.LMX_R8.All =0x0000; lmx.LMX_R7.All =0x0000; lmx.LMX_R4.All =0x0100; lmx.LMX_R2.All =0x0000; lmx.LMX_R1.All =0x0808; lmx.LMX_R0.All =0x2278; } void SetLmxFreq(void) { LL_mDelay(50); LmxWrite(0,0x2266); //reset device; en ld; pfd>10M;power up LL_mDelay(50); LmxWrite(70,lmx.LMX_R70.All); LmxWrite(69,lmx.LMX_R69.All); LmxWrite(68,lmx.LMX_R68.All); LmxWrite(64,lmx.LMX_R64.All); LmxWrite(62,lmx.LMX_R62.All); LmxWrite(61,lmx.LMX_R61.All); LmxWrite(59,lmx.LMX_R59.All); LmxWrite(48,lmx.LMX_R48.All); LmxWrite(47,lmx.LMX_R47.All); LmxWrite(46,lmx.LMX_R46.All); LmxWrite(45,lmx.LMX_R45.All); LmxWrite(44,lmx.LMX_R44.All); LmxWrite(43,lmx.LMX_R43.All); LmxWrite(42,lmx.LMX_R42.All); LmxWrite(41,lmx.LMX_R41.All); LmxWrite(40,lmx.LMX_R40.All); LmxWrite(39,lmx.LMX_R39.All); LmxWrite(38,lmx.LMX_R38.All); LmxWrite(37,lmx.LMX_R37.All); LmxWrite(36,lmx.LMX_R36.All); LmxWrite(35,lmx.LMX_R35.All); LmxWrite(34,lmx.LMX_R34.All); LmxWrite(33,lmx.LMX_R33.All); LmxWrite(32,lmx.LMX_R32.All); LmxWrite(31,lmx.LMX_R31.All); LmxWrite(30,lmx.LMX_R30.All); LmxWrite(29,lmx.LMX_R29.All); LmxWrite(28,lmx.LMX_R28.All); LmxWrite(25,lmx.LMX_R25.All); LmxWrite(24,lmx.LMX_R24.All); LmxWrite(23,lmx.LMX_R23.All); LmxWrite(22,lmx.LMX_R22.All); LmxWrite(21,lmx.LMX_R21.All); LmxWrite(20,lmx.LMX_R20.All); LmxWrite(19,lmx.LMX_R19.All); LmxWrite(14,lmx.LMX_R14.All); LmxWrite(13,lmx.LMX_R13.All); LmxWrite(12,lmx.LMX_R12.All); LmxWrite(11,lmx.LMX_R11.All); LmxWrite(10,lmx.LMX_R10.All); LmxWrite(9,lmx.LMX_R9.All); LmxWrite(8,lmx.LMX_R8.All); LmxWrite(7,lmx.LMX_R7.All); LmxWrite(3,lmx.LMX_R3.All); LmxWrite(2,lmx.LMX_R2.All); LmxWrite(1,lmx.LMX_R1.All); LmxWrite(0,lmx.LMX_R0.All); DELAY_Nop(500000); } //check LD //configure the register again,when check the LD is low void ConfigLmxAgain(void) { uint8_t LmxLdSta = 0x00; static uint8_t sChkLdDone = 0x00; gLmxLdSta = LL_GPIO_ReadInputPort(sLMX_MAP_T.LDO.gpio) &( 0x01 << sLMX_MAP_T.LDO.gpio_pin); //if(sChkLdDone != 0x00) //return; LmxLdSta = LL_GPIO_ReadInputPort(sLMX_MAP_T.LDO.gpio) & (0x01<9800.0){ } else if(freq>7100.0){ *chdiv_num = 1; //disable chdiv *vco_doubler=1;//enable vco doubler *vco_level=0; } else if(freq>6500.0){ *chdiv_num = 1; //disable chdiv *vco_doubler=0;//enable vco doubler *vco_level=1;//high level (REG30 7:6) } else if(freq>3550.0){ *chdiv_num = 1; //disable chdiv *vco_doubler=0;//disable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>1775.0){ *chdiv_num = 2; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>1184.0){ *chdiv_num = 3; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>888.0){ *chdiv_num = 4; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>592.0){ *chdiv_num = 6; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>444.0){ *chdiv_num = 8; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>296.0){ *chdiv_num = 12; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>222.0){ *chdiv_num = 16; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>148.0){ *chdiv_num = 24; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>111.0){ *chdiv_num = 32; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>99.0){ *chdiv_num = 36; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>74.0){ *chdiv_num = 48; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>56.0){ *chdiv_num = 64; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>37.0){ *chdiv_num = 96; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>28.0){ *chdiv_num = 128; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else if(freq>=20.0){ *chdiv_num = 192; //enable chdiv *vco_doubler=0;//enable vco doubler *vco_level=0;//low level (REG30 7:6) } else{ } } uint16_t REG46=0x1424; uint16_t REG47=0x08D4; uint16_t REG48=0x03FD; void LMX2592_SETOUT(uint16_t channel ,uint16_t state){ if(channel == 1){//cha if(state) REG47 = (REG47 & 0xEFFF); else REG47 = (REG47 & 0xEFFF) | 0x1000; LmxWrite(47,REG47); } if(channel == 2){//chb if(state) REG48 = (REG48 & 0xFFFD); else REG48 = (REG48 & 0xFFFD) | 0x0002; LmxWrite(48,REG48); } } void LMX2592_WRITE_FREQ(double freq){ // Fvco = Fpd x PLL_N_PRE x (PLL_N + PLL_NUM / PLL_DEN) // The VCO core covers an octave from 3.55 to 7.1 GHz. // F_PFD=20Mhz Fout = pfd * (N) / channel_div; input freq is in Mhz // denominator = 20M(0x0131 2D00 ) the resolution = 1Hz uint16_t chdiv_num; uint16_t vco_doubler; uint16_t vco_level; uint16_t FPFD=20; LMX2592_FIND_CHANNEL_DIV(freq,&chdiv_num,&vco_doubler,&vco_level); if(freq>5000){//pfd=5Mhz FPFD=5; LmxWrite(0,0x2206); //reset device; en ld;power up LmxWrite(1,0x0808);//cal_clk div=1;cal clk = 10Mhz LmxWrite(10,0x10d8);//disable multiplier //LmxWrite(9,0x0b02); LmxWrite(12,0x7002);//pll r pre div =2 LmxWrite(11,0x0018);//pll r div =1; set pfd = 20Mhz } else{//pfd=1Mhz FPFD=10; LmxWrite(0,0x2266); //reset device; en ld; pfd>10M;power up LmxWrite(1,0x0808);//cal_clk div=1;cal clk = 10Mhz LmxWrite(10,0x10d8);//disable multiplier LmxWrite(12,0x7001);//pll r pre div =10 1 LmxWrite(11,0x0018);//pll r div =1; set pfd = 1Mhz 1 } LmxWrite(37,0x5000); // presacle 4 1 LmxWrite(39,0x8104); LmxWrite(14,0x0084); // 1.25 MA printf("chdiv_num: %04d\r\n",chdiv_num); /****************** OUTPUT PART ********************/ if(chdiv_num == 1){ // Direct out through VCO if(vco_doubler == 1){ LmxWrite(30,0x0135);//enable vco doubler freq = freq/2; } else if(vco_level){ LmxWrite(30,0x01F4);//level = high( fvco>6500Mhz) } else { LmxWrite(30,0x0134);//level = low( fvco<6500Mhz) } LmxWrite(35,0x0019);//div0 LmxWrite(34,0xC3CA);// dis channel divider LmxWrite(31,0x0081);// LmxWrite(36,0x0000);//dis channel and out LmxWrite(46,REG46);// A level=20 ;dis out a & b; MASH_ORDER=3 REG47 = (REG47 & 0xF7FF) | 0x0800; LmxWrite(47,REG47);//Selects output from VCO REG48 = (REG48 & 0xFFFE) | 0x0001; LmxWrite(48,REG48); //Selects output from VCO } else {// use channel divider LmxWrite(13,4003); LmxWrite(30,0x0034);//level = low( fvco<6500Mhz) DIS vco doubler LmxWrite(31,0x0601);//dis vco buffer; en channel buffer 1 LmxWrite(34,0xC3EA);// en channel divider LmxWrite(46,REG46);// A level=20 ;dis out a & b; MASH_ORDER=3 REG47 = (REG47 & 0xF7FF) | 0x0000; LmxWrite(47,REG47);//Selects A output from channel divider REG48 = (REG48 & 0xFFFE); LmxWrite(48,REG48); //Selects B output from channel divider //write channel divider LMX2592_Wchannel_div(chdiv_num); } /****************** NDIV SET ********************/ double N_DIV = freq * (double)chdiv_num ; printf("N_DIV : %f\r\n",N_DIV); N_DIV = N_DIV/(FPFD); N_DIV = N_DIV/4; uint16_t N_integer = (uint16_t)N_DIV; double N_fraction = N_DIV - (double)N_integer; printf("N_fraction : %f\r\n",N_fraction); //write N_integer N_integer = (N_integer<<1)&(0x1FFE);//save 12bit printf("N_integer: %d\r\n",N_integer); LmxWrite(38,(N_integer));// pll Integer part of N-divider //write N_fraction N_fraction = N_fraction * 20000000; uint32_t N_frac_REG = (uint32_t)N_fraction; LmxWrite(44,(N_frac_REG>>16));//Numerator MSB of N-divider fraction LmxWrite(45,N_frac_REG);//Numerator LSB of N-divider fraction printf("N_frac_REG: %d %d\r\n",(N_frac_REG>>16),(N_frac_REG>>16)); //LmxWrite(40,0x0131);//Denominator MSB of N-divider fraction //LmxWrite(41,0x2d00);//Denominator LSB of N-divider fraction LmxWrite(40,0x0003);//Denominator MSB of N-divider fraction LmxWrite(41,0x0d40);//Denominator LSB of N-divider fraction //LmxWrite(47,0x18D4); LmxWrite(44,(N_frac_REG>>16));//Numerator MSB of N-divider fraction LmxWrite(45,N_frac_REG);//Numerator LSB of N-divider fraction /****************** STRAT WORK ********************/ if(FPFD == 1) LmxWrite(0,0x2278); //set pfd < 2.5Mhz else LmxWrite(0,0x220c | 0X0020); }