412 lines
12 KiB
C
412 lines
12 KiB
C
/*
|
|
* LMK_ClockTree.c
|
|
*
|
|
* Created on: 2019年3月5日
|
|
* Author: TiferKing
|
|
*/
|
|
|
|
#include "LMK_ClockTree.h"
|
|
|
|
__weak int LMK_CalPLL1CommonRate(LMK_Simple *SimpleConfig)
|
|
{
|
|
SimpleConfig->Generated.PLL1CommonRate = GreatestCommonDivisor(SimpleConfig->RefClockRate, SimpleConfig->VCOXClockRate);
|
|
LMK_AssertInValid(SimpleConfig->Generated.PLL1CommonRate);
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_CalPLL2CommonRate(LMK_Simple *SimpleConfig)
|
|
{
|
|
u8 i;
|
|
u64 PLL2CommonRate;
|
|
u64 ChMaxRate;
|
|
u64 RootDiv;
|
|
ChMaxRate = 0;
|
|
for(i = 0; i < 7; i++)
|
|
{
|
|
if(SimpleConfig->DClockRate[i] != 0)
|
|
{
|
|
if(ChMaxRate != 0)
|
|
{
|
|
ChMaxRate = LeastCommonMultiple(ChMaxRate, SimpleConfig->DClockRate[i]);
|
|
}
|
|
else
|
|
{
|
|
ChMaxRate = SimpleConfig->DClockRate[i];
|
|
}
|
|
}
|
|
}
|
|
LMK_AssertZero(ChMaxRate);
|
|
if((LMK_VCO0_RATE_L / ChMaxRate) < (LMK_VCO0_RATE_H / ChMaxRate))
|
|
{
|
|
RootDiv = (LMK_VCO0_RATE_L / ChMaxRate) + 1;
|
|
SimpleConfig->Generated.VCORate = RootDiv * ChMaxRate;
|
|
SimpleConfig->Generated.VCOSelect = 0;
|
|
}
|
|
else if((LMK_VCO1_RATE_L / ChMaxRate) < (LMK_VCO1_RATE_H / ChMaxRate))
|
|
{
|
|
RootDiv = (LMK_VCO1_RATE_L / ChMaxRate) + 1;
|
|
SimpleConfig->Generated.VCORate = RootDiv * ChMaxRate;
|
|
SimpleConfig->Generated.VCOSelect = 1;
|
|
}
|
|
else
|
|
{
|
|
return LMK_FAILURE;
|
|
}
|
|
PLL2CommonRate = GreatestCommonDivisor(SimpleConfig->Generated.VCORate / 2, SimpleConfig->VCOXClockRate);
|
|
LMK_AssertInValid(PLL2CommonRate);
|
|
SimpleConfig->Generated.PLL2CommonRate = PLL2CommonRate;
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_CalRegister(LMK_Simple *SimpleConfig)
|
|
{
|
|
int i;
|
|
LMK_AssertZero(SimpleConfig->SYSREFRate);
|
|
LMK_AssertZero(SimpleConfig->Generated.PLL1CommonRate);
|
|
LMK_AssertZero(SimpleConfig->Generated.PLL2CommonRate);
|
|
|
|
SimpleConfig->Generated.SYSREF_DIV = SimpleConfig->Generated.VCORate / SimpleConfig->SYSREFRate;
|
|
SimpleConfig->Generated.CLKin_R = SimpleConfig->RefClockRate / SimpleConfig->Generated.PLL1CommonRate;
|
|
SimpleConfig->Generated.PLL1_N = SimpleConfig->VCOXClockRate / SimpleConfig->Generated.PLL1CommonRate;
|
|
SimpleConfig->Generated.PLL2_R = SimpleConfig->VCOXClockRate / SimpleConfig->Generated.PLL2CommonRate;
|
|
SimpleConfig->Generated.PLL2_N = SimpleConfig->Generated.VCORate / SimpleConfig->Generated.PLL2CommonRate / 2;
|
|
for(i = 0; i < 7; i++)
|
|
{
|
|
SimpleConfig->Generated.DCLKout_Div[i] = SimpleConfig->DClockRate[i] == 0 ? 0 : SimpleConfig->Generated.VCORate / SimpleConfig->DClockRate[i];
|
|
}
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
int LMK_ConfigInitRegister(LMK_Config *DevConfig)
|
|
{
|
|
int i;
|
|
// Fixed Register Set
|
|
DevConfig->Config.Fixed_0 = 0x7F;
|
|
DevConfig->Config.Fixed_1 = 0x01;
|
|
DevConfig->Config.Fixed_2 = 0xAA;
|
|
DevConfig->Config.Fixed_3 = 0x02;
|
|
|
|
// Calculate Register Value
|
|
DevConfig->Config.OSCout_FMT = 4;
|
|
DevConfig->Config.OSCout_MUX = 0;
|
|
DevConfig->Config.VCO_MUX = 0;
|
|
|
|
DevConfig->Config.SYSREF_MUX = 0;
|
|
DevConfig->Config.SYSREF_CLKin0_MUX = 0;
|
|
|
|
DevConfig->Config.SYSREF_DIVH = 12;
|
|
DevConfig->Config.SYSREF_DIVL = 0;
|
|
|
|
DevConfig->Config.SYSREF_DDLYH = 0;
|
|
DevConfig->Config.SYSREF_DDLYL = 8;
|
|
|
|
DevConfig->Config.SYSREF_PULSE_CNT = 3;
|
|
|
|
DevConfig->Config.FB_MUX_EN = 0;
|
|
DevConfig->Config.FB_MUX = 0;
|
|
DevConfig->Config.PLL1_NCLK_MUX = 0;
|
|
DevConfig->Config.PLL2_NCLK_MUX = 0;
|
|
|
|
DevConfig->Config.SYSREF_PLSR_PD = 1;
|
|
DevConfig->Config.SYSREF_DDLY_PD = 1;
|
|
DevConfig->Config.SYSREF_PD = 1;
|
|
DevConfig->Config.SYSREF_GBL_PD = 0;
|
|
DevConfig->Config.OSCin_PD = 0;
|
|
DevConfig->Config.VCO_PD = 0;
|
|
DevConfig->Config.VCO_LDO_PD = 0;
|
|
DevConfig->Config.PLL1_PD = 0;
|
|
|
|
DevConfig->Config.DDLYd0_EN = 0;
|
|
DevConfig->Config.DDLYd2_EN = 0;
|
|
DevConfig->Config.DDLYd4_EN = 0;
|
|
DevConfig->Config.DDLYd6_EN = 0;
|
|
DevConfig->Config.DDLYd8_EN = 0;
|
|
DevConfig->Config.DDLYd10_EN = 0;
|
|
DevConfig->Config.DDLYd12_EN = 0;
|
|
DevConfig->Config.DDLYd0_SYSREF_EN = 0;
|
|
|
|
DevConfig->Config.DDLYd_STEP_CNT = 0;
|
|
|
|
DevConfig->Config.SYNC_MODE = 1;
|
|
DevConfig->Config.SYNC_PLL1_DLD = 0;
|
|
DevConfig->Config.SYNC_PLL2_DLD = 0;
|
|
DevConfig->Config.SYNC_EN = 1;
|
|
DevConfig->Config.SYNC_POL = 0;
|
|
DevConfig->Config.SYNC_1SHOT_EN = 0;
|
|
DevConfig->Config.SYSREF_CLR = 1;
|
|
|
|
DevConfig->Config.SYNC_DIS0 = 0;
|
|
DevConfig->Config.SYNC_DIS2 = 0;
|
|
DevConfig->Config.SYNC_DIS4 = 0;
|
|
DevConfig->Config.SYNC_DIS6 = 0;
|
|
DevConfig->Config.SYNC_DIS8 = 0;
|
|
DevConfig->Config.SYNC_DIS10 = 0;
|
|
DevConfig->Config.SYNC_DIS12 = 0;
|
|
DevConfig->Config.SYNC_DISSYSREF = 0;
|
|
|
|
DevConfig->Config.CLKin0_TYPE = 0;
|
|
DevConfig->Config.CLKin1_TYPE = 0;
|
|
DevConfig->Config.CLKin2_TYPE = 0;
|
|
DevConfig->Config.CLKin0_EN = 1;
|
|
DevConfig->Config.CLKin1_EN = 1;
|
|
DevConfig->Config.CLKin2_EN = 0;
|
|
|
|
DevConfig->Config.CLKin0_OUT_MUX = 2;
|
|
DevConfig->Config.CLKin1_OUT_MUX = 2;
|
|
DevConfig->Config.CLKin_SEL_MODE = 3;
|
|
DevConfig->Config.CLKin_SEL_POL = 0;
|
|
|
|
DevConfig->Config.CLKin_SEL0_TYPE = 2;
|
|
DevConfig->Config.CLKin_SEL0_MUX = 0;
|
|
|
|
DevConfig->Config.CLKin_SEL1_TYPE = 2;
|
|
DevConfig->Config.CLKin_SEL1_MUX = 0;
|
|
DevConfig->Config.SDIO_RDBK_TYPE = 1;
|
|
|
|
DevConfig->Config.RESET_TYPE = 2;
|
|
DevConfig->Config.RESET_MUX = 0;
|
|
|
|
DevConfig->Config.MAN_DACH = 2;
|
|
DevConfig->Config.MAN_DAC_EN = 1;
|
|
DevConfig->Config.HOLDOVER_FORCE = 0;
|
|
DevConfig->Config.TRACK_EN = 1;
|
|
DevConfig->Config.LOS_EN = 0;
|
|
DevConfig->Config.LOS_TIMEOUT = 0;
|
|
|
|
DevConfig->Config.MAN_DACL = 0;
|
|
|
|
DevConfig->Config.DAC_TRIP_LOW = 0;
|
|
|
|
DevConfig->Config.DAC_TRIP_HIGH = 0;
|
|
DevConfig->Config.DAC_CLK_MULT = 0;
|
|
|
|
DevConfig->Config.DAC_CLK_CNTR = 127;
|
|
|
|
DevConfig->Config.HOLDOVER_EN = 1;
|
|
DevConfig->Config.HOLDOVER_HITLESS_SW = 1;
|
|
DevConfig->Config.HOLDOVER_VTUNE_DET = 0;
|
|
DevConfig->Config.HOLDOVER_LOS_DET = 0;
|
|
DevConfig->Config.HOLDOVER_PLL1_DET = 0;
|
|
DevConfig->Config.CLKin_OVERRIDE = 0;
|
|
|
|
DevConfig->Config.HOLDOVER_DLD_CNTH = 2;
|
|
|
|
DevConfig->Config.HOLDOVER_DLD_CNTL = 0;
|
|
DevConfig->Config.CLKin0_RH = 0;
|
|
DevConfig->Config.CLKin0_RL = 120;
|
|
DevConfig->Config.CLKin1_RH = 0;
|
|
DevConfig->Config.CLKin1_RL = 150;
|
|
DevConfig->Config.CLKin2_RH = 0;
|
|
DevConfig->Config.CLKin2_RL = 150;
|
|
|
|
DevConfig->Config.PLL1_NH = 0;
|
|
DevConfig->Config.PLL1_NL = 120;
|
|
|
|
DevConfig->Config.PLL1_CP_GAIN = 4;
|
|
DevConfig->Config.PLL1_CP_POL = 1;
|
|
DevConfig->Config.PLL1_CP_TRI = 0;
|
|
DevConfig->Config.PLL1_WND_SIZE = 3;
|
|
|
|
DevConfig->Config.PLL1_DLD_CNTH = 32;
|
|
DevConfig->Config.PLL1_DLD_CNTL = 0;
|
|
|
|
DevConfig->Config.PLL1_N_DLY = 0;
|
|
DevConfig->Config.PLL1_R_DLY = 0;
|
|
|
|
DevConfig->Config.PLL1_LD_TYPE = 6;
|
|
DevConfig->Config.PLL1_LD_MUX = 1;
|
|
|
|
DevConfig->Config.PLL2_RH = 0;
|
|
DevConfig->Config.PLL2_RL = 2;
|
|
|
|
DevConfig->Config.PLL2_REF_2X_EN = 1;
|
|
DevConfig->Config.PLL2_XTAL_EN = 0;
|
|
DevConfig->Config.OSCin_FREQ = 7;
|
|
DevConfig->Config.PLL2_P = 2;
|
|
|
|
DevConfig->Config.PLL2_N_CALH = 0;
|
|
DevConfig->Config.PLL2_N_CALM = 0;
|
|
DevConfig->Config.PLL2_N_CALL = 12;
|
|
|
|
DevConfig->Config.PLL2_NH = 0;
|
|
DevConfig->Config.PLL2_FCAL_DIS = 0;
|
|
DevConfig->Config.PLL2_NM = 0;
|
|
DevConfig->Config.PLL2_NL = 12;
|
|
|
|
DevConfig->Config.PLL2_CP_TRI = 0;
|
|
DevConfig->Config.PLL2_CP_POL = 0;
|
|
DevConfig->Config.PLL2_CP_GAIN = 3;
|
|
DevConfig->Config.PLL2_WND_SIZE = 2;
|
|
|
|
DevConfig->Config.PLL2_DLD_CNTH = 32;
|
|
DevConfig->Config.SYSREF_REQ_EN = 0;
|
|
DevConfig->Config.PLL2_DLD_CNTL = 0;
|
|
|
|
DevConfig->Config.PLL2_LF_R3 = 0;
|
|
DevConfig->Config.PLL2_LF_R4 = 0;
|
|
|
|
DevConfig->Config.PLL2_LF_C3 = 0;
|
|
DevConfig->Config.PLL2_LF_C4 = 0;
|
|
DevConfig->Config.PLL2_LD_TYPE = 6;
|
|
DevConfig->Config.PLL2_LD_MUX = 2;
|
|
|
|
DevConfig->Config.PLL2_PD = 0;
|
|
DevConfig->Config.PLL2_PRE_PD = 0;
|
|
|
|
DevConfig->Config.VCO1_DIV = 0;
|
|
|
|
for(i = 0; i < 7; i++)
|
|
{
|
|
DevConfig->Config.Clock[i].DCLKout_Div = 0;
|
|
DevConfig->Config.Clock[i].CLKout_IDL = 0;
|
|
DevConfig->Config.Clock[i].CLKout_ODL = 0;
|
|
|
|
DevConfig->Config.Clock[i].DCLKout_DDLY_CNTL = 5;
|
|
DevConfig->Config.Clock[i].DCLKout_DDLY_CNTH = 5;
|
|
|
|
DevConfig->Config.Clock[i].DCLKout_MUX = 0;
|
|
DevConfig->Config.Clock[i].DCLKout_ADLY_MUX = 0;
|
|
DevConfig->Config.Clock[i].DCLKout_ALDY = 0;
|
|
|
|
DevConfig->Config.Clock[i].SDCLKout_HS = 0;
|
|
DevConfig->Config.Clock[i].SDCLKout_DDLY = 0;
|
|
DevConfig->Config.Clock[i].SDCLKout_MUX = 0;
|
|
DevConfig->Config.Clock[i].DCLKout_HS = 0;
|
|
|
|
DevConfig->Config.Clock[i].SDCLK_ADLY = 0;
|
|
DevConfig->Config.Clock[i].SDCLKout_ADLY_EN = 0;
|
|
|
|
DevConfig->Config.Clock[i].SDCLKout_PD = 1;
|
|
DevConfig->Config.Clock[i].SDCLKout_DIS_MODE = 0;
|
|
DevConfig->Config.Clock[i].CLKout_PD = 1;
|
|
DevConfig->Config.Clock[i].DCLKout_ADLY_PD = 1;
|
|
DevConfig->Config.Clock[i].DCLKout_ADLYg_PD = 1;
|
|
DevConfig->Config.Clock[i].DCLKout_HSg_PD = 1;
|
|
DevConfig->Config.Clock[i].DCLKout_DDLY_PD = 0;
|
|
|
|
DevConfig->Config.Clock[i].DCLKout_FMT = 0;
|
|
DevConfig->Config.Clock[i].DCLKout_POL = 0;
|
|
DevConfig->Config.Clock[i].SDCLKout_FMT = 0;
|
|
DevConfig->Config.Clock[i].SDCLKout_POL = 0;
|
|
}
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_ConfigSetRegister(LMK_Config *DevConfig, LMK_Simple *SimpleConfig)
|
|
{
|
|
UNUSED(DevConfig);
|
|
UNUSED(SimpleConfig);
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_ConfigPreset(LMK_Config *DevConfig, LMK_Simple *SimpleConfig)
|
|
{
|
|
UNUSED(DevConfig);
|
|
UNUSED(SimpleConfig);
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_ConfigCustomize(LMK_Config *DevConfig, LMK_Simple *SimpleConfig)
|
|
{
|
|
UNUSED(DevConfig);
|
|
UNUSED(SimpleConfig);
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_ConfigMake(LMK_Config *DevConfig, LMK_Simple *SimpleConfig)
|
|
{
|
|
LMK_AssertZero(SimpleConfig->InterfaceInst);
|
|
LMK_AssertFailure(LMK_CalPLL1CommonRate(SimpleConfig));
|
|
LMK_AssertFailure(LMK_CalPLL2CommonRate(SimpleConfig));
|
|
LMK_AssertFailure(LMK_CalRegister(SimpleConfig));
|
|
LMK_AssertFailure(LMK_ConfigInitRegister(DevConfig));
|
|
LMK_AssertFailure(LMK_ConfigSetRegister(DevConfig, SimpleConfig));
|
|
LMK_AssertFailure(LMK_ConfigPreset(DevConfig, SimpleConfig));
|
|
LMK_AssertFailure(LMK_ConfigCustomize(DevConfig, SimpleConfig));
|
|
DevConfig->InterfaceInst = SimpleConfig->InterfaceInst;
|
|
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
int LMK_Init(LMK_Config *DevConfig)
|
|
{
|
|
int i;
|
|
uint8_t tmp;
|
|
uint8_t ld1, ld2;
|
|
//Unlock SPI Register
|
|
LMK_RegUnlock(DevConfig);
|
|
|
|
//Reset Register
|
|
LMK_WriteReg(DevConfig, 0x000, 0x80);
|
|
|
|
//Enable 4-wire SPI
|
|
LMK_WriteReg(DevConfig, 0x000, 0x10);
|
|
|
|
//Sequence Program
|
|
LMK_WriteReg(DevConfig, 0x17C, 21);
|
|
LMK_WriteReg(DevConfig, 0x17D, 51);
|
|
for(i = 0; i < sizeof(DevConfig->Config); i++)
|
|
{
|
|
LMK_WriteReg(DevConfig, 0x100 + i, ((u8*)(&DevConfig->Config))[i]);
|
|
}
|
|
|
|
tmp = 1;
|
|
while(tmp)
|
|
{
|
|
LMK_ReadReg(DevConfig, 0x182, &ld1);
|
|
LMK_ReadReg(DevConfig, 0x183, &ld2);
|
|
tmp = (ld1 & 0x02) & (ld2 & 0x02) == 0x02 ? 1 : 0;
|
|
}
|
|
|
|
//Enable SYSREF
|
|
LMK_WriteReg(DevConfig, 0x140, 0xFB & ((u8*)(&DevConfig->Config))[0x040]); //SYSREF_PD = 0
|
|
LMK_WriteReg(DevConfig, 0x143, 0x7F & ((u8*)(&DevConfig->Config))[0x043]); //SYSREF_CLR = 0
|
|
/*LMK_WriteReg(DevConfig, 0x143, 0x80 | ((u8*)(&DevConfig->Config))[0x043]); //SYSREF_CLR = 1
|
|
LMK_WriteReg(DevConfig, 0x144, 0x00);
|
|
LMK_WriteReg(DevConfig, 0x143, 0x20 | ((u8*)(&DevConfig->Config))[0x043]); //SYNC_POL = 1
|
|
LMK_WriteReg(DevConfig, 0x143, 0xDF & ((u8*)(&DevConfig->Config))[0x043]); //SYNC_POL = 0
|
|
LMK_WriteReg(DevConfig, 0x144, 0xFF);
|
|
LMK_WriteReg(DevConfig, 0x143, 0x7F & ((u8*)(&DevConfig->Config))[0x043]); //SYSREF_CLR = 0
|
|
LMK_WriteReg(DevConfig, 0x139, ((u8*)(&DevConfig->Config))[0x039]); //SYSREF_MUX*/
|
|
|
|
LMK_RegLock(DevConfig);
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_StatusRead(LMK_Config *DevConfig)
|
|
{
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
int LMK_RegLock(LMK_Config *DevConfig)
|
|
{
|
|
LMK_WriteReg(DevConfig, 0x1FFD, 255);
|
|
LMK_WriteReg(DevConfig, 0x1FFE, 255);
|
|
LMK_WriteReg(DevConfig, 0x1FFF, 255);
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
int LMK_RegUnlock(LMK_Config *DevConfig)
|
|
{
|
|
LMK_WriteReg(DevConfig, 0x1FFD, 0);
|
|
LMK_WriteReg(DevConfig, 0x1FFE, 0);
|
|
LMK_WriteReg(DevConfig, 0x1FFF, 83);
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_WriteReg(LMK_Config *DevConfig, u16 RegisterAddress, u8 Value)
|
|
{
|
|
UNUSED(DevConfig);
|
|
UNUSED(RegisterAddress);
|
|
UNUSED(Value);
|
|
return LMK_SUCCESS;
|
|
}
|
|
|
|
__weak int LMK_ReadReg(LMK_Config *DevConfig, u16 RegisterAddress, u8 *Value)
|
|
{
|
|
UNUSED(DevConfig);
|
|
UNUSED(RegisterAddress);
|
|
UNUSED(Value);
|
|
return LMK_SUCCESS;
|
|
}
|