📄 drv399e.c
字号:
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_SYNTCTRL, F399_BYP, F399_BYP_L, &Data, 1, FALSE);
}
#endif
/*****************************************************
**FUNCTION :: FE_399_GetDivRatio
**ACTION :: Retreive the STV0399 synthesizer first divider ratio
**PARAMS IN :: hChip ==> handle to the chip
**PARAMS OUT:: NONE
**RETURN :: Ratio (1..15)
*****************************************************/
#ifndef STTUNER_MINIDRIVER
U8 FE_399_GetDivRatio(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
U8 ratio = 1,
byte,
nbbitused = 0,
nbbithigh = 0;
byte = STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_CMD_DIV);
while(((byte & 0x01) == 0x00) && (nbbitused <= 8))
{
byte >>=1;
nbbitused++;
}
while(((byte & 0x01) == 0x01) && (nbbitused <= 8))
{
byte >>=1;
nbbitused++;
nbbithigh++;
}
ratio = (nbbitused*2)-(nbbithigh-1);
return ratio;
}
#endif
#ifdef STTUNER_MINIDRIVER
U8 FE_399_GetDivRatio( )
{
U8 ratio = 1,Data,
byte,
nbbitused = 0,
nbbithigh = 0;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_DCLK2, F399_CMD_DIV, F399_CMD_DIV_L, &Data, 1, FALSE);
byte = Data;
while(((byte & 0x01) == 0x00) && (nbbitused <= 8))
{
byte >>=1;
nbbitused++;
}
while(((byte & 0x01) == 0x01) && (nbbitused <= 8))
{
byte >>=1;
nbbitused++;
nbbithigh++;
}
ratio = (nbbitused*2)-(nbbithigh-1);
return ratio;
}
#endif
/*-----------------------------------------------------------
-------------------------------------------------------------
-------------------------------------------------------------
**FUNCTION :: FE_399_GetMclkFreq
**ACTION :: Set the STV0399 master clock frequency
**PARAMS IN :: hChip ==> handle to the chip
** ExtClk ==> External clock frequency (Hz)
**PARAMS OUT:: NONE
**RETURN :: MasterClock frequency (Hz)
-------------------------------------------------------------*/
#ifndef STTUNER_MINIDRIVER
U32 FE_399_GetMclkFreq(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, U32 ExtClk)
{
U32 mclk = 0;
U32 pll_mc;
pll_mc = FE_399_Get_PLL_mult_coeff(DeviceMap,IOHandle);
switch(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_CMD_DIV_DIG))
{
default:
mclk = ExtClk; /* synthe bypass */
break;
case 1:
mclk = (ExtClk*pll_mc)/2; /* Divider bypass */
break;
case 2:
mclk = (ExtClk*pll_mc)/FE_399_GetDivRatio(DeviceMap,IOHandle);
break;
case 3:
mclk = (ExtClk*pll_mc)/(2*FE_399_GetDivRatio(DeviceMap,IOHandle));
break;
case 4:
mclk = (ExtClk*pll_mc)/(4*FE_399_GetDivRatio(DeviceMap,IOHandle));
break;
}
return mclk;
}
#endif
#ifdef STTUNER_MINIDRIVER
U32 FE_399_GetMclkFreq(U32 ExtClk)
{
U8 Data;
U32 mclk = 0;
U32 pll_mc;
pll_mc = FE_399_Get_PLL_mult_coeff( );
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_DCLK1, F399_CMD_DIV_DIG, F399_CMD_DIV_DIG_L, &Data, 1, FALSE);
switch(Data)
{
default:
mclk = ExtClk; /* synthe bypass */
break;
case 1:
mclk = (ExtClk*pll_mc)/2; /* Divider bypass */
break;
case 2:
mclk = (ExtClk*pll_mc)/FE_399_GetDivRatio( );
break;
case 3:
mclk = (ExtClk*pll_mc)/(2*FE_399_GetDivRatio( ));
break;
case 4:
mclk = (ExtClk*pll_mc)/(4*FE_399_GetDivRatio( ));
break;
}
return mclk;
}
#endif
/*----------------------------------------------------------------
------------------------------------------------------------------
------------------------------------------------------------------
**FUNCTION :: FE_399_SetTunerFreq
**ACTION :: Set the STV0399 analog synthetizer frequency
**PARAMS IN :: Quartz ==> quartz frequency (Hz)
** Frequency ==> tuner frequency (KHz)
**PARAMS OUT:: NONE
**RETURN :: tuner frequency (KHz)
------------------------------------------------------------------*/
#ifndef STTUNER_MINIDRIVER
U32 FE_399_SetTunerFreq(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 Quartz,U32 Frequency,U32 SymbolRate)
{
U32 result;
U32 pllmult = 0;
FE_399_PLL_MULTIPLIER_t pll;
if((Frequency >= 1400000000)&&(Frequency <= 1550000000))
{
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_PLL_DIV,0); /*pll_div = 32*/
}
else if((Frequency >= 1810000000)&&(Frequency <= 1860000000))
{
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_PLL_DIV,0); /*pll_div = 32*/
}
else
{
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_PLL_DIV,8); /* pll_div = 34 */
}
pll = (Frequency >= 1200000000) ? PLL_X5: PLL_X4;
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_PLL_FACTOR,pll); /* select pll */
pllmult = (pll == PLL_X4) ? 4:5;
result = FE_399_SetSyntFreq(DeviceMap,IOHandle,Quartz,Frequency/pllmult) * pllmult;
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_RESET_SYNT,1); /* Reset analog synthesizer */
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_RESET_SYNT,0);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_CMD,VCO_LOW);
STTUNER_IOREG_GetRegister(DeviceMap,IOHandle,R399_SYSCTRL);
if ((STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_VLOW)==0)||(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_VHIGH)==1))
{
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_CMD,VCO_HIGH);
}
return result;
}
#endif
#ifdef STTUNER_MINIDRIVER
U32 FE_399_SetTunerFreq(U32 Quartz,U32 Frequency,U32 SymbolRate)
{
U8 Data;
U32 result;
U32 pllmult = 0;
FE_399_PLL_MULTIPLIER_t pll;
if((Frequency >= 1400000000)&&(Frequency <= 1550000000))
{
Data = 0;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_DCLK1, F399_PLL_DIV, F399_PLL_DIV_L, &Data, 1, FALSE);
/*pll_div = 32*/
}
else if((Frequency >= 1810000000)&&(Frequency <= 1860000000))
{
Data = 0;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_DCLK1, F399_PLL_DIV, F399_PLL_DIV_L, &Data, 1, FALSE);
/*pll_div = 32*/
}
else
{
Data = 8;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_DCLK1, F399_PLL_DIV, F399_PLL_DIV_L, &Data, 1, FALSE);
/* pll_div = 34 */
}
pll = (Frequency >= 1200000000) ? PLL_X5: PLL_X4;
Data = pll;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_SYNTCTRL2, F399_PLL_FACTOR, F399_PLL_FACTOR_L, &Data, 1, FALSE);
/* select pll */
pllmult = (pll == PLL_X4) ? 4:5;
result = FE_399_SetSyntFreq(DeviceMap,IOHandle,Quartz,Frequency/pllmult) * pllmult;
Data = 1;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_SYNTCTRL2, F399_RESET_SYNT, F399_RESET_SYNT_L, &Data, 1, FALSE);
Data = 0;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_SYNTCTRL2, F399_RESET_SYNT, F399_RESET_SYNT_L, &Data, 1, FALSE);
Data = VCO_LOW;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_SYSCTRL, F399_CMD, F399_CMD_L, &Data, 1, FALSE);
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_SYSCTRL, 0, 0, &Data, 1, FALSE);
if ((((Data & 0x02)>>1)==0)||(((Data & 0x20)>>5)==1))
{
Data = VCO_HIGH;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_SYSCTRL, F399_CMD, F399_CMD_L, &Data, 1, FALSE);
}
return result;
}
#endif
/*****************************************************
**FUNCTION :: FE_399_AuxClkFreq
**ACTION :: Compute Auxiliary clock frequency
**PARAMS IN :: DigFreq ==> Frequency of the digital synthetizer (Hz)
** Prescaler ==> value of the prescaler
** Divider ==> value of the divider
**PARAMS OUT:: NONE
**RETURN :: Auxiliary Clock frequency
*****************************************************/
U32 FE_399_AuxClkFreq(U32 DigFreq,U32 Prescaler,U32 Divider)
{
U32 aclk,
factor;
switch(Prescaler)
{
case 0:
aclk = 0;
break;
case 1:
if(Divider)
aclk = DigFreq/2/Divider;
else
aclk = DigFreq/2;
break;
default:
factor = (U32)(2048L*FE_399E_PowOf2(Prescaler-2));
if(factor)
aclk = DigFreq/factor/(32+Divider);
else
aclk = 0;
break;
}
return aclk;
}
/*****************************************************
**FUNCTION :: FE_399_F22Freq
**ACTION :: Compute F22 frequency
**PARAMS IN :: DigFreq ==> Frequency of the digital synthetizer (Hz)
** F22 ==> Content of the F22 register
**PARAMS OUT:: NONE
**RETURN :: F22 frequency
*****************************************************/
U32 FE_399_F22Freq(U32 DigFreq,U32 F22)
{
return (F22!=0) ? (DigFreq/(32*F22)) : 0;
}
FE_399_SIGNALTYPE_t FE_399_LockAgc0and1(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,FE_399_InternalParams_t *pParams)
{
U32 agc0int;
U8 temp[2];
S32 agc1gain = 0;
#ifndef STTUNER_MINIDRIVER
agc0int = 5;
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_AGC0_INT,agc0int);
STTUNER_IOREG_GetContigousRegisters(DeviceMap,IOHandle,R399_AGC1S,2,temp);
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle, R399_AGC1S, temp, 2); /* Write into AGC1 registers to force update */
WAIT_N_MS_399(2);
agc1gain = FE_399_CalcAGC1Gain(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_AGC1_INT_PRIM))/2;
do
{
if(agc1gain < 11)
{
agc0int = MAX(1,agc0int-1);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_AGC0_INT,agc0int); /* Write AGC0 integrator */
STTUNER_IOREG_GetContigousRegisters(DeviceMap,IOHandle,R399_AGC1S,2,temp);
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R399_AGC1S,temp,2); /* Write into AGC1 registers to force update */
}
else if(agc1gain > 19)
{
agc0int = MIN(9,agc0int+1);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_AGC0_INT,agc0int); /* Write AGC0 integrator */
STTUNER_IOREG_GetContigousRegisters(DeviceMap,IOHandle,R399_AGC1S,2,temp);
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R399_AGC1S,temp,2); /* Write into AGC1 registers to force update */
}
WAIT_N_MS_399(2);
agc1gain = FE_399_CalcAGC1Gain(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_AGC1_INT_PRIM))/2;
}while(((agc1gain < 11) || (agc1gain > 19)) && (agc0int != 1) && (agc0int != 9));
pParams->State = AGC1OK_399E;
#endif
/********************MINIDRIVER*****************
************************************************/
#ifdef STTUNER_MINIDRIVER
U8 Data, nsbuffer[2];
agc0int = 5;
Data = agc0int;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_AGC0I, F399_AGC0_INT, F399_AGC0_INT_L, &Data, 1, FALSE);
nsbuffer[0] = 195;
nsbuffer[1] = 191;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_AGC1S, 0, 0, nsbuffer, 2, FALSE);
WAIT_N_MS_399(2);
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_AGC1P, F399_AGC1_INT_PRIM, F399_AGC1_INT_PRIM_L, &Data, 1, FALSE);
agc1gain = FE_399_CalcAGC1Gain(Data)/2;
do
{
if(agc1gain < 11)
{
agc0int = MAX(1,agc0int-1);
Data = agc0int;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_AGC0I, F399_AGC0_INT, F399_AGC0_INT_L, &Data, 1, FALSE);
nsbuffer[0] = 195;
nsbuffer[1] = 191;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_AGC1S, 0, 0, nsbuffer, 2, FALSE);
}
else if(agc1gain > 19)
{
agc0int = MIN(9,agc0int+1);
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_AGC0I, F399_AGC0_INT, F399_AGC0_INT_L, &Data, 1, FALSE);
nsbuffer[0] = 195;
nsbuffer[1] = 191;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_AGC1S, 0, 0, nsbuffer, 2, FALSE);
}
WAIT_N_MS_399(2);
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_AGC1P, F399_AGC1_INT_PRIM, F399_AGC1_INT_PRIM_L, &Data, 1, FALSE);
agc1gain = FE_399_CalcAGC1Gain(Data/2);
}while(((agc1gain < 11) || (agc1gain > 19)) && (agc0int != 1) && (agc0int != 9));
pParams->State = AGC1OK_399E;
#endif
return pParams->State;
}
/*****************************************************
--FUNCTION :: FE_399_CheckTiming
--ACTION :: Check for timing locked
--PARAMS IN :: pParams->Ttiming => Time to wait for timing loop locked
--PARAMS OUT:: pParams->State => result of the check
--RETURN :: NOTIMING_399E if timing not locked, TIMINGOK_399E otherwise
--***************************************************/
FE_399_SIGNALTYPE_t FE_399_CheckTiming(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,FE_399_InternalParams_t *pParams)
{
int locked;
U32 timing;
#ifndef STTUNER_MINIDRIVER
WAIT_N_MS_399(pParams->Ttiming);
locked=STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_TMG_LOCK_IND);
timing=(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_TIMING_LOOP_FREQ));
#endif
#ifdef STTUNER_MINIDRIVER
U8 Data;
WAIT_N_MS_399(pParams->Ttiming);
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_TLIR, F399_TMG_LOCK_IND, F399_TMG_LOCK_IND_L, &Data, 1, FALSE);
locked = (int)Data;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_RTF, F399_TIMING_LOOP_FREQ, F399_TIMING_LOOP_FREQ_L, &Data, 1, FALSE);
timing = ((U32)Data - (1 << 8));
#endif
if(locked >= 42)
{
if((locked > 48) && (timing >= 110))
pParams->State = ANALOGCARRIER_399E;
else
pParams->State = TIMINGOK_399E;
}
else
pParams->State = NOTIMING_399E;
return pParams->State;
}
/*****************************************************
--FUNCTION :: FE_399_CheckCarrier
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -