drv0288.c
来自「st7710的tuner标准驱动」· C语言 代码 · 共 1,598 行 · 第 1/4 页
C
1,598 行
PhaseNumber[6] = {2,6,4,6,14,8},
averaging[4] = {1024,4096,16384,65536},
InnerCode = 1000,
HigherRate = 1000;
U32 i;
U8 Pr,Sn,To,Hy;
/*=======================================================================
-- Data capture time (in ms)
-- -------------------------
-- This time is due to the Viterbi synchronisation.
--
-- For each authorized inner code, the Viterbi search time is calculated,
-- and the results are cumulated in ViterbiSearch.
-- InnerCode is multiplied by 1000 in order to obtain timings in ms
=======================================================================*/
Pr=STTUNER_IOREG_GetRegister(DeviceMap,IOHandle,R288_PR);
STTUNER_IOREG_GetRegister(DeviceMap,IOHandle,R288_VAVSRCH);
Sn=STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_SN);
To=STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_TO);
Hy=STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_H);
for(i=0;i<6;i++)
{
if (((Pr >> i)& 0x01) == 0x01)
{
switch(i)
{
case 0: /* inner code 1/2 */
InnerCode = 2000; /* 2.0 */
break;
case 1: /* inner code 2/3 */
InnerCode = 1500; /* 1.5 */
break;
case 2: /* inner code 3/4 */
InnerCode = 1333; /* 1.333 */
break;
case 3: /* inner code 5/6 */
InnerCode = 1200; /* 1.2 */
break;
case 4: /* inner code 6/7 */
InnerCode = 1167; /* 1.667 */
break;
case 5: /* inner code 7/8 */
InnerCode = 1143; /* 1.143 */
break;
}
Tviterbi += (2*PhaseNumber[i]*averaging[Sn]*InnerCode);
if(HigherRate < InnerCode)
HigherRate = InnerCode;
}
}
/* Time out calculation (TimeOut)
-- ------------------------------
-- This value indicates the maximum duration of the synchro word research. */
TimeOut = (U32)(HigherRate * 16384L * (1L<<To)); /* 16384= 16x1024 bits */
/* Hysteresis duration (Hysteresis)
-- ------------------------------ */
THysteresis = (U32)(HigherRate * 26112L * (1L<<Hy)); /* 26112= 16x204x8 bits */
Tdata =((Tviterbi + TimeOut + THysteresis) / (2*(U32)SymbolRate));
/* a guard time of 1 mS is added */
return (1L + (long)Tdata);
}
/****************************************************
**FUNCTION :: FE_288_GetRollOff
**ACTION :: Read the rolloff value
**PARAMS IN :: DeviceMap ==> Handle for the chip
**PARAMS OUT:: NONE
**RETURN :: rolloff
*****************************************************/
int FE_288_GetRollOff(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
if (STTUNER_IOREG_GetField(DeviceMap, IOHandle, F288_MODE_COEF) == 1)
return 20;
else
return 35;
}
/*****************************************************
**FUNCTION :: FE_288_CalcDerotFreq
**ACTION :: Compute Derotator frequency
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: Derotator frequency (KHz)
*****************************************************/
S32 FE_288_CalcDerotFreq(U8 derotmsb,U8 derotlsb,U32 fm)
{
S32 dfreq;
S32 Itmp;
Itmp = (S16)(derotmsb<<8)+derotlsb;
dfreq = (S32)(Itmp*(fm/10000L));
dfreq = (S32)(dfreq / 65536L);
dfreq *= 10;
return dfreq;
}
/*****************************************************
**FUNCTION :: FE_288_GetDerotFreq
**ACTION :: Read current Derotator frequency
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: Derotator frequency (KHz)
*****************************************************/
S32 FE_288_GetDerotFreq(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 MasterClock)
{
U8 cfrm[2];
/* Read registers */
STTUNER_IOREG_GetContigousRegisters(DeviceMap,IOHandle,R288_CFRM,2,cfrm);
return FE_288_CalcDerotFreq(cfrm[0],cfrm[1],MasterClock);
}
/*****************************************************
**FUNCTION :: FE_288_SetDerotFreq
**ACTION :: Set current Derotator frequency
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void FE_288_SetDerotFreq(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 MasterClock_Hz,S32 DerotFreq_Hz)
{
S16 s16;
U8 TMP[2];
s16=(S16)(DerotFreq_Hz/(S32)(MasterClock_Hz/65536L));
TMP[0]=MSB_288(s16);
TMP[1]=LSB_288(s16);
/* write registers */
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R288_CFRM,TMP,2);
}
/*****************************************************
**FUNCTION :: FE_288_CalcSymbolRate
**ACTION :: Compute symbol frequency
**PARAMS IN :: Hbyte -> High order byte
** Mbyte -> Mid byte
** Lbyte -> Low order byte
**PARAMS OUT:: NONE
**RETURN :: Symbol frequency
*****************************************************/
U32 FE_288_CalcSymbolRate(U32 MasterClock,U8 Hbyte,U8 Mbyte,U8 Lbyte)
{
U32 Ltmp,
Ltmp2,
Mclk;
Mclk = (U32)(MasterClock / 4096L); /* MasterClock*10/2^20 */
Ltmp = (((U32)Hbyte<<12)+((U32)Mbyte<<4))/16;
Ltmp *= Mclk;
Ltmp /=16;
Ltmp2=((U32)Lbyte*Mclk)/256;
Ltmp+=Ltmp2;
return Ltmp;
}
/*****************************************************
**FUNCTION :: FE_288_SetSymbolRate
**ACTION :: Set symbol frequency
**PARAMS IN :: DeviceMap -> handle to the chip
** MasterClock -> Masterclock frequency (Hz)
** SymbolRate -> symbol rate (bauds)
**PARAMS OUT:: NONE
**RETURN :: Symbol frequency
*****************************************************/
U32 FE_288_SetSymbolRate(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 MasterClock,U32 SymbolRate)
{
U32 U32Tmp;
U8 TMP[3];
U8 TMPUP[3];
U8 TEMP[2];
/*
** in order to have the maximum precision, the symbol rate entered into
** the chip is computed as the closest value of the "true value".
** In this purpose, the symbol rate value is rounded (1 is added on the bit
** below the LSB_288 )
*/
U32Tmp = (U32)FE_288_BinaryFloatDiv(SymbolRate,MasterClock,20);
TMP[0]=0x80 ;
TMP[1]=0x00;
TMP[2]=0x00;
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R288_SFRH,TMP,3); /* warning : symbol rate is set to Masterclock/2 before setting the real value !!!!! */
TMPUP[0]=(U32Tmp>>12)&0xFF;
TMPUP[1]=(U32Tmp>>4)&0xFF;
TMPUP[2]=U32Tmp&0x0F;
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R288_SFRH,TMPUP,3);
TEMP[0]=0;
TEMP[1]=0;
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R288_RTFM,TEMP,2); /* reset timing offset */
return(SymbolRate) ;
}
/*****************************************************
**FUNCTION :: FE_288_GetSymbolRate
**ACTION :: Get the current symbol rate
**PARAMS IN :: DeviceMap -> handle to the chip
** MasterClock -> Masterclock frequency (Hz)
**PARAMS OUT:: NONE
**RETURN :: Symbol rate
*****************************************************/
U32 FE_288_GetSymbolRate(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 MasterClock)
{
U8 sfrh[3];
STTUNER_IOREG_GetContigousRegisters(DeviceMap,IOHandle,R288_SFRH,3,sfrh);
return FE_288_CalcSymbolRate( MasterClock,
sfrh[0],
sfrh[1],
sfrh[2] );
}
/*****************************************************
--FUNCTION :: CarrierWidth
--ACTION :: Compute the width of the carrier
--PARAMS IN :: SymbolRate -> Symbol rate of the carrier (Kbauds or Mbauds)
-- RollOff -> Rolloff * 100
--PARAMS OUT:: NONE
--RETURN :: Width of the carrier (KHz or MHz)
--***************************************************/
long FE_288_CarrierWidth(long SymbolRate, long RollOff)
{
return (SymbolRate + (SymbolRate*RollOff)/100);
}
/****************************************************
--FUNCTION :: FE_288_CheckRange
--ACTION :: Check if the founded frequency is in the correct range
--PARAMS IN :: Params->BaseFreq =>
--PARAMS OUT:: Params->State => Result of the check
--RETURN :: RANGEOK_288 if check success, OUTOFRANGE_288 otherwise
--***************************************************/
FE_288_SIGNALTYPE_t FE_288_CheckRange(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,FE_288_InternalParams_t *Params, U32 SymbolRate)
{
int RangeOffset_Khz,
TransponderFrequency_Khz;
RangeOffset_Khz = Params->SearchRange/2000;
TransponderFrequency_Khz = Params->Frequency + ((S32)Params->TunerIQSense*FE_288_GetDerotFreq(DeviceMap,IOHandle,Params->MasterClock));
if(SymbolRate!=0)
{
if(((TransponderFrequency_Khz >= Params->BaseFreq - RangeOffset_Khz)
&& (TransponderFrequency_Khz <= Params->BaseFreq + RangeOffset_Khz)) &&
((Params->Results.Symbolrate >= SymbolRate - 300000)
&& (Params->Results.Symbolrate <= SymbolRate + 300000)))
{Params->State = RANGEOK_288;}
else
{Params->State = OUTOFRANGE_288;}
}
else
{
if((TransponderFrequency_Khz >= Params->BaseFreq - RangeOffset_Khz)
&& (TransponderFrequency_Khz <= Params->BaseFreq + RangeOffset_Khz))
{Params->State = RANGEOK_288;}
else
{Params->State = OUTOFRANGE_288;}
}
return Params->State;
}
void FE_288_NextSubRange(FE_288_InternalParams_t *Params)
{
S32 OldSubRange;
if(Params->SubDir > 0)
{
OldSubRange = Params->SubRange;
Params->SubRange = MIN_288( (S32)(Params->SearchRange/2) - (Params->TunerOffset + Params->SubRange/2) , Params->SubRange);
if(Params->SubRange<=0)
Params->SubRange = 0;
Params->TunerOffset = Params->TunerOffset + ((OldSubRange + Params->SubRange)/2 );
}
Params->Frequency = Params->BaseFreq + (Params->SubDir * Params->TunerOffset)/1000;
Params->SubDir = -Params->SubDir;
}
S16 FE_288_GetRFLevel(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
S32 Imin, agcGain = 0, Imax, i, rfLevel = 0;
FE_288_LOOKUP_t *lookup;
lookup = &FE_288_RF_LookUp;
if((lookup != NULL) && lookup->size)
{
agcGain = (S8)STTUNER_IOREG_GetField(DeviceMap, IOHandle, F288_AGC1_VALUE);
Imin = 0;
Imax = lookup->size-1;
if(INRANGE_288(lookup->table[Imin].regval,agcGain,lookup->table[Imax].regval))
{
while((Imax-Imin)>1)
{
i=(Imax+Imin)/2;
if(INRANGE_288(lookup->table[Imin].regval,agcGain,lookup->table[i].regval))
Imax = i;
else
Imin = i;
}
rfLevel = (((S32)agcGain - lookup->table[Imin].regval)
* (lookup->table[Imax].realval - lookup->table[Imin].realval)
/ (lookup->table[Imax].regval - lookup->table[Imin].regval))
+ lookup->table[Imin].realval;
}
else
rfLevel = 0;
}
return rfLevel - 100;
}
/*****************************************************
--FUNCTION :: FE_288_GetCarrierToNoiseRatio
--ACTION :: Return the carrier to noise of the current carrier
--PARAMS IN :: NONE
--PARAMS OUT:: NONE
--RETURN :: C/N of the carrier, 0 if no carrier
--***************************************************/
S32 FE_288_GetCarrierToNoiseRatio(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
S32 c_n = 0,
regval,
Imin,
Imax,
i;
U8 nirm[2];
FE_288_LOOKUP_t *lookup;
lookup = &FE_288_CN_LookUp;
if(STTUNER_IOREG_GetField(DeviceMap, IOHandle, F288_CF))
{
if((lookup != NULL) && lookup->size)
{
STTUNER_IOREG_GetContigousRegisters(DeviceMap,IOHandle,R288_NIRM,2,nirm);
regval = MAKEWORD_288(nirm[0],nirm[1]);
Imin = 0;
Imax = lookup->size-1;
if(INRANGE_288(lookup->table[Imin].regval,regval,lookup->table[Imax].regval))
{
while((Imax-Imin)>1)
{
i=(Imax+Imin)/2;
if(INRANGE_288(lookup->table[Imin].regval,regval,lookup->table[i].regval))
Imax = i;
else
Imin = i;
}
c_n = ((regval - lookup->table[Imin].regval)
* (lookup->table[Imax].realval - lookup->table[Imin].realval)
/ (lookup->table[Imax].regval - lookup->table[Imin].regval))
+ lookup->table[Imin].realval;
}
else
c_n = 100;
if(c_n>=100)
c_n = 100;
}
}
return c_n;
}
U32 FE_288_GetError(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?