tinySG/MDK-ARM/lmx2595.c

649 lines
16 KiB
C
Raw Normal View History

2025-01-08 00:18:38 +08:00
#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);
//<2F><><EFBFBD><EFBFBD><EFBFBD>غ<EFBFBD>΢С<CEA2><D0A1>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ȡMISO<53><4F><EFBFBD><EFBFBD>//
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();
//<2F><><EFBFBD><EFBFBD><EFBFBD>غ<EFBFBD>΢С<CEA2><D0A1>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ȡMISO<53><4F><EFBFBD><EFBFBD>//
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;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>//
uint16_t lmxRead(uint8_t regadr)
{
uint16_t rddat;
regadr = regadr|0x80; //<2F><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>1<EFBFBD><31>ȷ<EFBFBD><C8B7>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>//
Lmx_CSB_RESET(); //Ƭѡ<C6AC>ź<EFBFBD><C5BA><EFBFBD><EFBFBD><EFBFBD>//
DELAY_Nop(50);
Lmx_SCK_RESET();
DELAY_Nop(50);
spi_8bit(regadr); //<2F>ͳ<EFBFBD><CDB3><EFBFBD>ַ//
rddat=spi_16bit(0); //<2F>ͳ<EFBFBD>16λ<36><CEBB>Ч<EFBFBD><D0A7><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD>ڻض<DABB><D8B6>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>//
DELAY_Nop(50);
Lmx_CSB_SET(); //ƬѡʧЧ//
return rddat;
}
void LmxWrite(uint8_t regadr,uint16_t dat)
{
2025-04-05 16:27:54 +08:00
printf("write addr 0x%02x 0x%04x\r\n",regadr,dat);
2025-01-08 00:18:38 +08:00
regadr=regadr&0x7f; //<2F><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>0<EFBFBD><30>ȷ<EFBFBD><C8B7>Ϊд<CEAA><D0B4><EFBFBD><EFBFBD>//
Lmx_CSB_RESET(); //Ƭѡ<C6AC>ź<EFBFBD><C5BA><EFBFBD><EFBFBD><EFBFBD>//
DELAY_Nop(50);
Lmx_SCK_RESET();
DELAY_Nop(50);
spi_8bit(regadr); //<2F>ͳ<EFBFBD><CDB3><EFBFBD>ַ//
spi_16bit(dat); //<2F>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>//
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;
2025-04-05 16:27:54 +08:00
lmx.LMX_R68.All= 0x0000;
lmx.LMX_R64.All= 0x0000;
2025-01-08 00:18:38 +08:00
lmx.LMX_R62.All= 0x0000;
2025-04-05 16:27:54 +08:00
lmx.LMX_R61.All= 0x0000;
2025-01-08 00:18:38 +08:00
lmx.LMX_R59.All= 0x0000;
lmx.LMX_R48.All= 0x03FC;
2025-04-05 16:27:54 +08:00
lmx.LMX_R47.All= 0x00D4;
lmx.LMX_R46.All= 0x1421;
2025-01-08 00:18:38 +08:00
lmx.LMX_R45.All= 0x0000;
lmx.LMX_R44.All= 0x0000;
2025-04-05 16:27:54 +08:00
lmx.LMX_R43.All= 0x0000;
2025-01-08 00:18:38 +08:00
lmx.LMX_R42.All= 0x0000;
2025-04-05 16:29:06 +08:00
lmx.LMX_R41.All= 0x0001;
lmx.LMX_R40.All= 0x0000;
2025-01-08 00:18:38 +08:00
lmx.LMX_R39.All= 0x8104;
2025-04-05 16:29:06 +08:00
lmx.LMX_R38.All= 0x0960;
2025-01-08 00:18:38 +08:00
lmx.LMX_R37.All= 0x5000;
2025-04-05 16:27:54 +08:00
lmx.LMX_R36.All= 0x0C44;
lmx.LMX_R35.All= 0x119B;
2025-01-08 00:18:38 +08:00
lmx.LMX_R34.All= 0xC3EA;
2025-04-05 16:27:54 +08:00
lmx.LMX_R33.All= 0x0000;
lmx.LMX_R32.All= 0x0000;
lmx.LMX_R31.All= 0x0601;
2025-04-05 16:29:06 +08:00
lmx.LMX_R30.All= 0x0134;
2025-04-05 16:27:54 +08:00
lmx.LMX_R29.All= 0x0000;
lmx.LMX_R28.All= 0x0000;
2025-01-08 00:18:38 +08:00
lmx.LMX_R25.All= 0x0000;
2025-04-05 16:27:54 +08:00
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;
2025-04-05 16:29:06 +08:00
lmx.LMX_R14.All= 0x039C;
2025-01-08 00:18:38 +08:00
lmx.LMX_R13.All= 0x4003;
2025-04-05 16:29:06 +08:00
lmx.LMX_R12.All= 0x7001;
lmx.LMX_R11.All= 0x0148;
2025-01-08 00:18:38 +08:00
lmx.LMX_R10.All= 0x10D8;
2025-04-05 16:29:06 +08:00
lmx.LMX_R9.All =0x0800;
2025-04-05 16:27:54 +08:00
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;
2025-04-05 16:29:06 +08:00
lmx.LMX_R0.All =0x2278;
2025-01-08 00:18:38 +08:00
}
void SetLmxFreq(void)
{
LL_mDelay(50);
2025-04-05 16:27:54 +08:00
LmxWrite(0,0x2266); //reset device; en ld; pfd>10M;power up
LL_mDelay(50);
2025-01-08 00:18:38 +08:00
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<<sLMX_MAP_T.LDO.gpio_pin);
if(LmxLdSta != 0x00)
return;
SetLmxFreq();
sChkLdDone = 0xaa;
}
void LMX2592_Wchannel_div(uint16_t chdiv_num){
switch(chdiv_num){
case 2:
LmxWrite(35,0x001B);
LmxWrite(36,0x0C10);
break;
case 3:
LmxWrite(35,0x001d); //ti lmx2592 datasheet has an error in REG35 !!!!
LmxWrite(36,0x0C10);
break;
case 4:
LmxWrite(35,0x029B);
LmxWrite(36,0x0C20);
break;
case 6:
LmxWrite(35,0x029d);
LmxWrite(36,0x0C20);
break;
case 8:
LmxWrite(35,0x049B);
LmxWrite(36,0x0C20);
break;
case 12:
LmxWrite(35,0x049d);
LmxWrite(36,0x0C20);
break;
case 16:
LmxWrite(35,0x109B);
LmxWrite(36,0x0C20);
break;
case 24:
LmxWrite(35,0x109d);
LmxWrite(36,0x0C20);
break;
case 32:
LmxWrite(35,0x119B);
LmxWrite(36,0x0C41);
break;
case 36:
LmxWrite(35,0x099d);
LmxWrite(36,0x0C41);
break;
case 48:
LmxWrite(35,0x119d);
LmxWrite(36,0x0C41);
break;
case 64:
LmxWrite(35,0x119B);
LmxWrite(36,0x0C42);
break;
case 96:
LmxWrite(35,0x119B);
LmxWrite(36,0x0C44);
break;
case 128:
LmxWrite(35,0x119B);
LmxWrite(36,0x0C48);
break;
case 192:
LmxWrite(35,0x119d);
LmxWrite(36,0x0C48);
break;
default:
LmxWrite(35,0x119B);
LmxWrite(36,0x0C48);
}
}
void LMX2592_FIND_CHANNEL_DIV(float freq,uint16_t *chdiv_num,uint16_t *vco_doubler,uint16_t *vco_level){
2025-04-05 16:27:54 +08:00
printf("freq: %f\r\n",freq);
if(freq>9800.0){
2025-01-08 00:18:38 +08:00
}
2025-04-05 16:27:54 +08:00
else if(freq>7100.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 1; //disable chdiv
*vco_doubler=1;//enable vco doubler
*vco_level=0;
}
2025-04-05 16:27:54 +08:00
else if(freq>6500.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 1; //disable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=1;//high level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>3550.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 1; //disable chdiv
*vco_doubler=0;//disable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>1775.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 2; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>1184.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 3; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>888.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 4; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>592.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 6; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>444.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 8; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>296.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 12; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>222.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 16; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>148.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 24; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>111.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 32; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>99.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 36; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>74.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 48; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>56.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 64; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>37.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 96; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>28.0){
2025-01-08 00:18:38 +08:00
*chdiv_num = 128; //enable chdiv
*vco_doubler=0;//enable vco doubler
*vco_level=0;//low level (REG30 7:6)
}
2025-04-05 16:27:54 +08:00
else if(freq>=20.0){
2025-01-08 00:18:38 +08:00
*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
2025-04-05 16:27:54 +08:00
FPFD=10;
LmxWrite(0,0x2266); //reset device; en ld; pfd>10M;power up
2025-01-08 00:18:38 +08:00
LmxWrite(1,0x0808);//cal_clk div=1;cal clk = 10Mhz
LmxWrite(10,0x10d8);//disable multiplier
2025-04-05 16:27:54 +08:00
LmxWrite(12,0x7001);//pll r pre div =10 1
2025-01-08 00:18:38 +08:00
LmxWrite(11,0x0018);//pll r div =1; set pfd = 1Mhz 1
2025-04-05 16:27:54 +08:00
}
LmxWrite(37,0x5000); // presacle 4 1
LmxWrite(39,0x8104);
LmxWrite(14,0x0084); // 1.25 MA
printf("chdiv_num: %04d\r\n",chdiv_num);
2025-01-08 00:18:38 +08:00
/****************** 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 ;
2025-04-05 16:27:54 +08:00
printf("N_DIV : %f\r\n",N_DIV);
2025-01-08 00:18:38 +08:00
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;
2025-04-05 16:27:54 +08:00
printf("N_fraction : %f\r\n",N_fraction);
2025-01-08 00:18:38 +08:00
//write N_integer
N_integer = (N_integer<<1)&(0x1FFE);//save 12bit
2025-04-05 16:27:54 +08:00
printf("N_integer: %d\r\n",N_integer);
2025-01-08 00:18:38 +08:00
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
2025-04-05 16:27:54 +08:00
printf("N_frac_REG: %d %d\r\n",(N_frac_REG>>16),(N_frac_REG>>16));
2025-01-08 00:18:38 +08:00
//LmxWrite(40,0x0131);//Denominator MSB of N-divider fraction
//LmxWrite(41,0x2d00);//Denominator LSB of N-divider fraction
2025-04-05 16:27:54 +08:00
LmxWrite(40,0x0003);//Denominator MSB of N-divider fraction
LmxWrite(41,0x0d40);//Denominator LSB of N-divider fraction
2025-01-08 00:18:38 +08:00
//LmxWrite(47,0x18D4);
2025-04-05 16:27:54 +08:00
LmxWrite(44,(N_frac_REG>>16));//Numerator MSB of N-divider fraction
LmxWrite(45,N_frac_REG);//Numerator LSB of N-divider fraction
2025-01-08 00:18:38 +08:00
/****************** STRAT WORK ********************/
if(FPFD == 1)
LmxWrite(0,0x2278); //set pfd < 2.5Mhz
else
LmxWrite(0,0x220c | 0X0020);
}