📄 d0899_dvbs2util.c
字号:
/* -------------------------------------------------------------------------
File Name: drv0899_dvbs2util.c
Description: STB0899 driver LLA V2.0.0 18/04/2005
author: SD
Description: STB0899 driver LLA V3.0.3 05/07/2005
author: SD
Date 29/03/06
Description: STB0899 driver LLA V3.6.0 integration
author: HS
---------------------------------------------------------------------------- */
/* includes ---------------------------------------------------------------- */
#include "ioreg.h"
#include "d0899_init.h"
#include "sttuner.h"
#include "d0899_util.h"
#include "d0899_dvbs2util.h"
#include "stcommon.h"
#define ESNO_AVE 3
#define ESNO_QUANT 32
#define AVEFRAMES_COARSE 10
#define AVEFRAMES_FINE 20
#define MISS_THRESHOLD 6
#define UWP_THRESHOLD_ACQ 1125
#define UWP_THRESHOLD_TRACK 758
#define UWP_THRESHOLD_SOF 1350
#define SOF_SEARCH_TIMEOUT 1664100
/*****************************************************
**FUNCTION :: FE_DVBS2_SetCarrierFreq
**ACTION :: Set the nominal frequency for carrier search
**PARAMS IN :: hChip ==> handle to the chip
:: CarrierFreq ==> carrier frequency in MHz.
:: MasterClock ==> demod clock in MHz.
**PARAMS OUT:: NONE
**RETURN :: None
*****************************************************/
void FE_DVBS2_SetCarrierFreq(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,S32 CarrierFreq,U32 MasterClock)
{
S32 crlNomFreq;
crlNomFreq=(FE_899_PowOf2(CRL_NCO_BITS))/MasterClock;
crlNomFreq*=CarrierFreq;
/*ChipSetFieldImage(DeviceMap,IOHandle,FSTB0899_CRLNOM_FREQ,crlNomFreq);*/
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_CRLNOMFREQ,crlNomFreq);
}
/*****************************************************
**FUNCTION :: FE_DVBS2_GetSymbolRate
**ACTION :: Return the DVBS2 Symbol Rate
**PARAMS IN :: hChip ==> handle to the chip
:: MasterClock ==> demod clock in Hz.
**PARAMS OUT:: NONE
**RETURN :: Symbol Rate in Symb/s
*****************************************************/
U32 FE_DVBS2_GetSymbolRate(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 MasterClock)
{
U32 bTrNomFreq,
symbolRate,
decimRate,
intval1,intval2;
int div1,div2,rem1,rem2;
div1=BTR_NCO_BITS/2;
div2=BTR_NCO_BITS-div1-1;
bTrNomFreq=STTUNER_IOREG_GetRegister(DeviceMap,IOHandle,RSTB0899_BTRNOMFREQ);
decimRate=STTUNER_IOREG_GetField_SizeU32(DeviceMap,IOHandle,FSTB0899_DECIM_RATE,FSTB0899_DECIM_RATE_INFO);
decimRate=FE_899_PowOf2(decimRate);
intval1=MasterClock/FE_899_PowOf2(div1);
intval2=bTrNomFreq/FE_899_PowOf2(div2);
rem1=MasterClock%FE_899_PowOf2(div1);
rem2=bTrNomFreq%FE_899_PowOf2(div2);
symbolRate=(intval1*intval2)+((intval1*rem2)/FE_899_PowOf2(div2))+((intval2*rem1)/FE_899_PowOf2(div1)); /*only for integer calculation */
symbolRate/=decimRate; /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */
return symbolRate;
}
/*****************************************************
**FUNCTION :: DVBS2CalclSymbRate
**ACTION :: Compute the value of the register BTRNOMFREQ
according to the given Symbol Rate
**PARAMS IN :: SymbolRate ==> Symbol rate in Symb/s.
:: MasterClock ==> demod clock in Hz.
**PARAMS OUT:: NONE
**RETURN :: BTRNOMFREQ reg value
*****************************************************/
U32 DVBS2CalclSymbRate(U32 SymbolRate,U32 MasterClock)
{
U32 decimRatio,
decimRate,
decimation,
remain,
intval,
btrNomFreq;
decimRatio = (MasterClock*2) / (5 * SymbolRate);
decimRatio = (decimRatio == 0) ? 1 : decimRatio;
decimRate = Log2Int(decimRatio);
decimation=1<<decimRate;
MasterClock/=1000; /* for integer Caculation*/
SymbolRate/=1000; /* for integer Caculation*/
if(decimation<=4)
{
intval=(decimation*FE_899_PowOf2(BTR_NCO_BITS-1))/MasterClock;
remain= (decimation*FE_899_PowOf2(BTR_NCO_BITS-1))%MasterClock;
}
else
{
intval = FE_899_PowOf2(BTR_NCO_BITS-1)/(MasterClock/100) * decimation/100;
remain = (decimation*FE_899_PowOf2(BTR_NCO_BITS-1))%MasterClock;
}
btrNomFreq =(intval*SymbolRate)+((remain*SymbolRate)/MasterClock);
return btrNomFreq;
}
/*****************************************************
**FUNCTION :: CalcCorrection
**ACTION :: Compute the coorection to be applied to the symbol rate,
Field BTRFREQ_CORR.
**PARAMS IN :: SymbolRate ==> Symbol rate in Symb/s.
:: MasterClock ==> demod clock in Hz.
**PARAMS OUT:: NONE
**RETURN :: BTRFREQ_CORR Field value
*****************************************************/
U32 CalcCorrection(U32 SymbolRate,U32 MasterClock)
{
U32 decimRatio,
decimRate,
correction;
decimRatio = (MasterClock*2) / (5 * SymbolRate);
decimRatio = (decimRatio == 0) ? 1 : decimRatio;
MasterClock/=1000; /* for integer Caculation*/
SymbolRate/=1000; /* for integer Caculation*/
correction=(512*MasterClock)/(2*decimRatio*SymbolRate);
return correction;
}
/*****************************************************
**FUNCTION :: FE_DVBS2_SetSymbolRate
**ACTION :: Set the DVBS2 Symbol Rate.
**PARAMS IN :: hChip ==> handle to the chip
:: SymbolRate ==> Symbol rate in Symb/s.
:: MasterClock ==> demod clock in Hz.
**PARAMS OUT:: NONE
**RETURN :: None
*****************************************************/
void FE_DVBS2_SetSymbolRate(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 SymbolRate,U32 MasterClock)
{
U32 decimRatio,
decimRate,
winSel,
decimation,
fSymovSr,
btrNomFreq,
correction,
freqAdjScl,
bandLimit,
decimcntrlreg;
/*set decimation to 1*/
decimRatio = (MasterClock*2) / (5 * SymbolRate);
decimRatio = (decimRatio == 0) ? 1 : decimRatio;
decimRate = Log2Int(decimRatio);
winSel=0;
if(decimRate >= 5)
winSel = decimRate - 4;
decimation =(1<<decimRate);
fSymovSr=MasterClock/((decimation*SymbolRate)/1000); /* (FSamp/Fsymbol *100) for integer Caculation */
if(fSymovSr<=2250) /* don't band limit signal going into btr block*/
bandLimit=1;
else
bandLimit=0; /* band limit signal going into btr block*/
decimcntrlreg=((winSel<<3)&0x18)+((bandLimit<<5)&0x20)+(decimRate&0x7);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_DECIMCNTRL,decimcntrlreg);
if(fSymovSr<=3450)
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_ANTIALIASSEL,0);
else if(fSymovSr<=4250)
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_ANTIALIASSEL,1);
else
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_ANTIALIASSEL,2);
btrNomFreq=DVBS2CalclSymbRate(SymbolRate,MasterClock);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_BTRNOMFREQ,btrNomFreq);
correction=CalcCorrection(SymbolRate,MasterClock);
STTUNER_IOREG_SetField_SizeU32(DeviceMap, IOHandle,FSTB0899_BTRFREQ_CORR,FSTB0899_BTRFREQ_CORR_INFO,correction);
/* scale UWP+CSM frequency to sample rate*/
freqAdjScl = SymbolRate /( MasterClock/4096);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_FREQADJSCALE,freqAdjScl);
}
/*****************************************************
**FUNCTION :: FE_DVBS2_SetBtrLoopBW
**ACTION :: Set the Bit Timing loop bandwidth
as a percentage of the symbol rate .
**PARAMS IN :: hChip ==> handle to the chip
:: LoopBW ==> Timing loop bandwidth parameters.
**PARAMS OUT:: NONE
**RETURN :: None
*****************************************************/
void FE_DVBS2_SetBtrLoopBW(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, FE_DVBS2_LoopBW_Params_t LoopBW)
{
S32 decimRatio,
decimRate,
kbtr1Rshft,
kbtr1,
kbtr0Rshft,
kbtr0,
kbtr2Rshft,
kDirectShift,
kIndirectShift;
U32 decimation,
K,
wn,
kDirect,
kIndirect,
val;
decimRatio = (LoopBW.MasterClock*2) / (5 * LoopBW.SymbolRate);
decimRatio = (decimRatio == 0) ? 1 : decimRatio;
decimRate = Log2Int(decimRatio);
decimation = (1<<decimRate);
LoopBW.SymPeakVal=LoopBW.SymPeakVal*576000;
K=FE_899_PowOf2(BTR_NCO_BITS)/(LoopBW.MasterClock/1000);
K*=(LoopBW.SymbolRate/1000000)*decimation; /*k=k 10^-8*/
K=LoopBW.SymPeakVal/K;
if(K!=0)
{
wn = (4*LoopBW.Zeta*LoopBW.Zeta)+1000000;
wn=(2 * (LoopBW.LoopBwPercent*1000)*40*LoopBW.Zeta)/wn; /*wn =wn 10^-8*/
kIndirect = (wn*wn)/K;
kIndirect=kIndirect; /*kindirect = kindirect 10^-6*/
kDirect=(2*wn*LoopBW.Zeta)/K; /*kDirect = kDirect 10^-2*/
kDirect*=100;
kDirectShift=Log2Int(kDirect)-Log2Int(10000)-2;
kbtr1Rshft = (-1*kDirectShift)+BTR_GAIN_SHIFT_OFFSET;
kbtr1=kDirect/FE_899_PowOf2(kDirectShift);
kbtr1/=10000;
kIndirectShift = Log2Int(kIndirect+15)-20 /*- 2*/;
kbtr0Rshft = (-1* kIndirectShift)+BTR_GAIN_SHIFT_OFFSET ;
kbtr0=kIndirect*FE_899_PowOf2(-kIndirectShift);
kbtr0/=1000000;
kbtr2Rshft = 0;
if( kbtr0Rshft > 15)
{
kbtr2Rshft= kbtr0Rshft - 15;
kbtr0Rshft = 15;
}
val=(kbtr0Rshft & 0xf)+((kbtr0 & 0xf)<<4)+((kbtr1Rshft & 0xf)<<8)+((kbtr1 & 0xf)<<12)+((kbtr2Rshft & 0xf)<<16);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_BTRLOOPGAIN,val);
}
else
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_BTRLOOPGAIN,/*0xd6d5f*/0xc4c4f);
}
/*****************************************************
**FUNCTION :: FE_DVBS2_BtrInit
**ACTION :: Init the timming loop
**PARAMS IN :: hChip ==> handle to the chip
**PARAMS OUT:: NONE
**RETURN :: None
*****************************************************/
void FE_DVBS2_BtrInit(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
/* set enable BTR loopback*/
STTUNER_IOREG_SetField_SizeU32(DeviceMap, IOHandle,FSTB0899_INTRP_PHS_SENS,FSTB0899_INTRP_PHS_SENS_INFO,1);
STTUNER_IOREG_SetField_SizeU32(DeviceMap, IOHandle,FSTB0899_BTRERR_ENA,FSTB0899_BTRERR_ENA_INFO,1);
/* fix btr freq accum at 0*/
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_BTRFREQINIT, 0x10000000);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_BTRFREQINIT, 0x00000000);
/* fix btr freq accum at 0*/
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_BTRPHSINIT, 0x10000000);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_BTRPHSINIT, 0x00000000);
}
/*****************************************************
**FUNCTION :: FE_DVBS2_ConfigUWP
**ACTION :: Configure the UWP state machine
**PARAMS IN :: hChip ==> handle to the chip
:: UWPparams ==> UWP parameters.
**PARAMS OUT:: NONE
**RETURN :: None
*****************************************************/
void FE_DVBS2_ConfigUWP(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,FE_DVBS2_UWPConfig_Params_t UWPparams)
{
U32 val;
/*Set Fields image value*/
/*
STTUNER_IOREG_SetField_SizeU32(DeviceMap, IOHandle,FSTB0899_UWP_ESN0_AVE,FSTB0899_UWP_ESN0_AVE_INFO,UWPparams.EsNoAve);
STTUNER_IOREG_SetField_SizeU32(DeviceMap, IOHandle,FSTB0899_UWP_ESN0_QUANT,FSTB0899_UWP_ESN0_QUANT_INFO,UWPparams.EsNoQuant);
STTUNER_IOREG_SetField_SizeU32(DeviceMap, IOHandle,FSTB0899_UWP_THRESHOLD_SOF,FSTB0899_UWP_THRESHOLD_SOF_INFO,UWPparams.ThresholdSof);
*/
val=((UWPparams.EsNoAve & 0x3)<<1)+((UWPparams.EsNoQuant & 0xFF)<<3)+((UWPparams.ThresholdSof & 0x7FFF)<<11);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_UWPCNTRL1,val);
/*ChipSetFieldImage(hChip,FSTB0899_FE_COARSE_TRK,UWPparams.AveFramesCoarse);
ChipSetFieldImage(hChip,FSTB0899_FE_FINE_TRK,UWPparams.AveframesFine);
ChipSetFieldImage(hChip,FSTB0899_UWP_MISS_THRESHOLD,UWPparams.MissThreshold);*/
val=(UWPparams.AveFramesCoarse & 0xFF)+((UWPparams.AveframesFine & 0xFF)<<8)+((UWPparams.MissThreshold & 0xFF)<<16);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_UWPCNTRL2,val);
/*ChipSetFieldImage(hChip,FSTB0899_UWP_THRESHOLD_ACQ,UWPparams.ThresholdAcq);
ChipSetFieldImage(hChip,FSTB0899_UWP_THRESHOLD_TRACK,UWPparams.ThresholdTrack);*/
val=(UWPparams.ThresholdAcq & 0x7FFF)+ ((UWPparams.ThresholdTrack & 0x7FFF)<<15);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_UWPCNTRL3,val);
STTUNER_IOREG_SetRegister(DeviceMap, IOHandle,RSTB0899_SOFSRCHTO,UWPparams.SofSearchTimeout);
}
/*****************************************************
**FUNCTION :: FE_DVBS2_GetUWPstate
**ACTION :: Read the UWP status locked or not
**PARAMS IN :: hChip ==> handle to the chip
:: TimeOut ==> timeout to wait for UWP lock
**PARAMS OUT:: NONE
**RETURN :: UWP state
*****************************************************/
int FE_DVBS2_GetUWPstate(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,int TimeOut)
{
int Time=0,
locked=0,
i,
lkn=0;
while((Time<TimeOut)&& (locked==0))
{
locked=STTUNER_IOREG_GetField_SizeU32(DeviceMap,IOHandle,FSTB0899_UWP_LOCK,FSTB0899_UWP_LOCK_INFO);
WAIT_N_MS_899(1);
Time++;
}
return locked;
}
/*****************************************************
**FUNCTION :: FE_DVBS2_GetModCod
**ACTION :: Read the found MODCODE
**PARAMS IN :: hChip ==> handle to the chip
**PARAMS OUT:: NONE
**RETURN :: Found MODCODE
*****************************************************/
U32 FE_DVBS2_GetModCod(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
return(STTUNER_IOREG_GetField_SizeU32(DeviceMap,IOHandle,FSTB0899_UWP_DECODED_MODCODE,FSTB0899_UWP_DECODED_MODCODE_INFO)>>2);
}
/*****************************************************
**FUNCTION :: FE_DVBS2_GetUWPEsNo
**ACTION :: Read the Es/N0 indicator
**PARAMS IN :: hChip ==> handle to the chip
**PARAMS OUT:: NONE
**RETURN :: Es/N0
*****************************************************/
S32 FE_DVBS2_GetUWPEsNo(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,S32 Quant)
{
U32 tempus;
tempus=STTUNER_IOREG_GetField_SizeU32(DeviceMap,IOHandle,FSTB0899_ESN0_ESR,FSTB0899_ESN0_ESR_INFO);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -