📄 drv0288.c
字号:
{
U32 ber = 0,i;
STTUNER_IOREG_GetRegister(DeviceMap,IOHandle,R288_ACLC);
STTUNER_IOREG_GetRegister(DeviceMap,IOHandle,R288_ERRCTRL);
STTUNER_IOREG_GetRegister(DeviceMap,IOHandle,R288_VSTATUS);
FE_288_GetErrorCount(DeviceMap,IOHandle,COUNTER1_288); /* remove first counter value */
/* Average 5 ber values */
for(i=0;i<3;i++)
{
WAIT_N_MS_288(100);
ber += FE_288_GetErrorCount(DeviceMap,IOHandle,COUNTER1_288);
}
ber/=3;
/* Check for carrier */
if(STTUNER_IOREG_GetField(DeviceMap, IOHandle, F288_CF))
{
if(!STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_ERRMODE))
{
/* Error Rate */
ber *= 9766;
/* theses two lines => ber = ber * 10^7 */
ber /= (U32)FE_288_PowOf2(2 + 2*STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_NOE));
switch(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_ERR_SOURCE))
{
case 0 : /* QPSK bit errors */
ber /= 8;
switch(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_PR))
{
case 0: /* PR 1/2 */
ber *= 1;
ber /= 2;
break;
case 1: /* PR 2/3 */
ber *= 2;
ber /= 3;
break;
case 2: /* PR 3/4 */
ber *= 3;
ber /= 4;
break;
case 3: /* PR 5/6 */
ber *= 5;
ber /= 6;
break ;
case 4: /* PR 6/7 */
ber *= 6;
ber /= 7;
break;
case 5: /* PR 7/8 */
ber *= 7;
ber /= 8;
break;
default :
ber = 0;
break;
}
break;
case 1: /* Viterbi bit errors */
ber /= 8;
break;
case 2: /* Viterbi byte errors */
break;
case 3: /* Packet errors */
if(STTUNER_IOREG_GetField(DeviceMap, IOHandle, F288_FECMODE) != 0x04)
ber *= 204; /* DVB */
else
ber *= 147; /* DirecTV */
break;
}
}
}
return ber;
}
S32 FE_288_Coarse(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 MasterClock_Hz,S32 *Offset_Khz)
{
S32 Symbolrate = 0;
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_FINE,0);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_AUTOCENTRE,0);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_COARSE,1);
WAIT_N_MS_288(50);/* run coarse during 50ms */
Symbolrate = (S32)FE_288_GetSymbolRate(DeviceMap,IOHandle,MasterClock_Hz); /* Get result of coarse algorithm */
*Offset_Khz = FE_288_GetDerotFreq(DeviceMap,IOHandle,MasterClock_Hz); /* Read derotator offset */
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_COARSE,0); /* stop coarse algorithm */
return Symbolrate;
}
void FE_288_Fine(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 MasterClock_Hz,U32 Symbolrate, BOOL fine_scan )
{
U32 i=0,
fmin = 0,
fmax = 0;
U8 fminm[5];
/* fine initialisation */
if(fine_scan == TRUE )
{
/* +/- 15% search range */
fmin = ((((U32)(Symbolrate/(U32)1000))*((85*32768)/100))/(U32)(MasterClock_Hz/(U32)1000)); /* 2^15=32768*/
fmax = ((((U32)(Symbolrate/1000))*((115*32768)/100))/(U32)(MasterClock_Hz/1000));
FE_288_SetSymbolRate(DeviceMap,IOHandle,MasterClock_Hz,(U32)((Symbolrate*11)/10));/*1.4*/
}
else
{
if(Symbolrate <= 6000000)
{
fmin = ((((U32)(Symbolrate/(U32)1000))*((85*32768)/100))/(U32)(MasterClock_Hz/(U32)1000)); /* 2^15=32768*/
fmax = ((((U32)(Symbolrate/1000))*((115*32768)/100))/(U32)(MasterClock_Hz/1000));
FE_288_SetSymbolRate(DeviceMap,IOHandle,MasterClock_Hz,(U32)((Symbolrate*11)/10));
}
else
{
fmin = ((((U32)(Symbolrate/(U32)1000))*((95*32768)/100))/(U32)(MasterClock_Hz/(U32)1000)); /* 2^15=32768*/
fmax = ((((U32)(Symbolrate/1000))*((105*32768)/100))/(U32)(MasterClock_Hz/1000));
/*FE_288_SetSymbolRate(DeviceMap,IOHandle,MasterClock_Hz,(U32)((Symbolrate)));*/
}
}
fminm[0]=MSB_288((U32)fmin);
fminm[0] |= 0x80; /* set F288_STOP_ON_FMIN to 1 */
fminm[1]=LSB_288((U32)fmin);
fminm[2]=MSB_288((U32)fmax);
fminm[3]=LSB_288((U32)fmax);
fminm[4]=MAX_288(Symbolrate/1000000,1); /* Refresh fine increment */
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R288_FMINM,fminm,5); /*Update all fine registers*/
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_FINE,1); /* start fine algorithm */
i=0;
do
{
WAIT_N_MS_288(10);
i++;
}while(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_FINE)/* && (i<1000)*/); /* wait for end of fine algorithm */
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_FINE,0);
}
S32 FE_288_Autocentre(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
S32 timeout=0,
timing;
U8 rtfm[2];
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_AUTOCENTRE,1); /* Start autocentre algorithm */
do
{
WAIT_N_MS_288(10); /* wait 10 ms */
timeout++;
STTUNER_IOREG_GetContigousRegisters(DeviceMap,IOHandle,R288_RTFM,2,rtfm);
timing = (short int)MAKEWORD_288(rtfm[0],rtfm[1]);
}while((ABS_288(timing)>300) && (timeout<100)); /* timing loop is centered or timeout limit is reached */
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_AUTOCENTRE,0); /* Stop autocentre algorithm */
return timing;
}
BOOL FE_288_WaitLock(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, S32 TData)
{
S32 timeout=0;
BOOL lock;
do
{
WAIT_N_MS_288(1); /* wait 1 ms */
timeout++;
lock=STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_LK);
}while(!lock && (timeout<TData));
return lock;
}
FE_288_SIGNALTYPE_t FE_288_Algo(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, FE_288_InternalParams_t *Params, STTUNER_Handle_t TopLevelHandle)
{
FE_288_SIGNALTYPE_t signalType=NOAGC1_288;
S32 TransponderFreq;
S32 coarseOffset_Khz=0,coarseSymbolRate_Bds=0, tdata, nbErr, maxPckError;
ST_ErrorCode_t Error=ST_NO_ERROR;
STTUNER_InstanceDbase_t *Inst;
STTUNER_tuner_instance_t *TunerInstance;
S16 timing, Kt;
U32 SymbolRate;
U8 symbolrate_ok,
lock,
direcTV = 0;
U8 cfrm[2];
BOOL fine_scan = TRUE;
Inst = STTUNER_GetDrvInst();
/* get the tuner instance for this driver from the top level handle */
TunerInstance = &Inst[TopLevelHandle].Sat.Tuner;
Params->Frequency = Params->BaseFreq;
SymbolRate = Params->Symbolrate;
Params->SubDir = 1;
Params->TunerOffset = 0;
Params->SubRange = 15000000;
if(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_FECMODE)==4)
direcTV = 1; /* Store current FEC mode */
do
{
TransponderFreq = Params->Frequency ;
Error = (TunerInstance->Driver->tuner_SetFrequency)(TunerInstance->DrvHandle, (U32)Params->Frequency, (U32 *)&Params->Frequency);
if(Error != ST_NO_ERROR)
{
return(NOAGC1_288);
}
Params->FreqOffset = (S32)((TransponderFreq - Params->Frequency)*1000);
Params->DerotFreq = (short int)(((short int)Params->TunerIQSense)*(Params->FreqOffset/(S32)Params->Mclk));
Kt = 56;
do
{
Error = (TunerInstance->Driver->tuner_SetBandWidth)( TunerInstance->DrvHandle,50000000/1000, &(Params->TunerBW));
/* ALPHA and BETA are in the same register ==> this I2C access update both */
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_ALPHA,7);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_BETA,28);
if(direcTV)
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_SYM,0);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_KT,Kt);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_FROZE_LOCK,1);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_IND1_ACC,0);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_IND2_ACC,0xff);
FE_288_SetSymbolRate(DeviceMap,IOHandle,Params->MasterClock,1000000);/* Set symbolrate to 1.000MBps (minimum symbol rate) */
cfrm[0]=MSB_288(Params->DerotFreq);
cfrm[1]=LSB_288(Params->DerotFreq);
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R288_CFRM,cfrm,2); /* reset derotator frequency */
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_CFD_ON,1);
coarseSymbolRate_Bds=FE_288_Coarse(DeviceMap,IOHandle,Params->MasterClock,&coarseOffset_Khz); /* Symbolrate coarse search */
Params->FreqOffset = coarseOffset_Khz*1000;
Params->DerotFreq = (short int)(((short int)Params->TunerIQSense)*(Params->FreqOffset/(S32)Params->Mclk));
if(Inst[TopLevelHandle].Sat.ScanExact)
{
#ifdef STTUNER_DRV_SAT_SCR
if((Inst[TopLevelHandle].Capability.SCREnable)&& (Inst[TopLevelHandle].CurrentTunerInfo.ScanInfo.LNB_SignalRouting == STTUNER_VIA_SCRENABLED_LNB))
{
FE_288_SetSymbolRate(DeviceMap,IOHandle,Params->MasterClock,Params->Symbolrate); /* force symbolrate */
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_COARSE,1);
WAIT_N_MS_288(5);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_COARSE,0);
}
else
{
FE_288_SetSymbolRate(DeviceMap,IOHandle,Params->MasterClock,Params->Symbolrate);
}
#else
FE_288_SetSymbolRate(DeviceMap,IOHandle,Params->MasterClock,Params->Symbolrate);
#endif
}
else
{
Params->Symbolrate=coarseSymbolRate_Bds;
}
if(Params->Symbolrate>1000) /* to avoid a divide by zero error */
symbolrate_ok = Params->MasterClock/(Params->Symbolrate/1000)>2100;
else
symbolrate_ok = TRUE;
if(Params->Symbolrate <= 6000000)
{
Params->MinOffset = -2000;
Params->MaxOffset = 2000;
}
if((Params->Symbolrate>1000000) /* Check symbolrate value */
&& (coarseOffset_Khz>=Params->MinOffset) /* Check minimum derotator offset criteria */
&& (coarseOffset_Khz<Params->MaxOffset) /* Check maximum derotator offset criteria */
&& (symbolrate_ok)) /* Check shannon criteria */
{
if(Inst[TopLevelHandle].Sat.ScanExact)
Error = (TunerInstance->Driver->tuner_SetBandWidth)( TunerInstance->DrvHandle,(((Params->Symbolrate*14)/10)+4000000)/1000, &(Params->TunerBW));
else
Error = (TunerInstance->Driver->tuner_SetBandWidth)( TunerInstance->DrvHandle,(Params->Symbolrate*3)/1000, &(Params->TunerBW));
/* Adjust carrier loop setting */
if(Params->Symbolrate < 5000000)
{
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_ALPHA,8);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_BETA,17);
}
else if(Params->Symbolrate > 35000000)
{
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_ALPHA,8);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_BETA,36);
}
if(Inst[TopLevelHandle].Sat.ScanExact)
{
fine_scan = FALSE;
}
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_FROZE_LOCK,0); /* if timing loop not locked launch fine algorithm */
FE_288_Fine(DeviceMap,IOHandle,Params->MasterClock,Params->Symbolrate, fine_scan);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_CFD_ON,0);
timing = FE_288_Autocentre(DeviceMap,IOHandle);
if(!STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_CF) && (Params->Symbolrate>18000000))
{
FE_288_SetSymbolRate(DeviceMap,IOHandle,Params->MasterClock,Params->Symbolrate);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_CFD_ON,1); /* Frequency offset detector on */
cfrm[0]=0;
cfrm[1]=0;
STTUNER_IOREG_SetContigousRegisters(DeviceMap,IOHandle,R288_CFRM,cfrm,2); /* reset derotator frequency */
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_CFD_ON,0); /* Frequency offset detector off */
timing = FE_288_Autocentre(DeviceMap,IOHandle);
}
if(ABS_288(timing)<=300)
{
Params->Results.Symbolrate=FE_288_GetSymbolRate(DeviceMap,IOHandle,Params->MasterClock);
tdata=10+(S32)(2*FE_288_DataTimeConstant(DeviceMap,IOHandle,Params->Results.Symbolrate));
lock=FE_288_WaitLock(DeviceMap,IOHandle,tdata);
if(lock)
{
/* Store puncture rate */
Params->Results.PunctureRate= 1<<STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_PR); /* Store puncture rate */
}
if(direcTV)
{
/* workaround for IQ invertion in DIRECTV mode */
WAIT_N_MS_288(4);
nbErr = FE_288_GetErrorCount(DeviceMap,IOHandle,COUNTER2_288);
maxPckError = 0x01<<(11+2*STTUNER_IOREG_GetField(DeviceMap,IOHandle,F288_NOE2)); /* packet error rate = 50% */
if((!lock) || (lock && (Params->Results.PunctureRate == STTUNER_FEC_6_7) && (nbErr>maxPckError)))
{
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_SYM,1);
lock=FE_288_WaitLock(DeviceMap,IOHandle,tdata);
}
}
if(lock)
{
signalType = FE_288_CheckRange(DeviceMap,IOHandle,Params, SymbolRate);
Params->Results.SignalType = signalType;
/* update results */
Params->Results.Frequency = Params->Frequency + ((S32)Params->TunerIQSense*FE_288_GetDerotFreq(DeviceMap,IOHandle,Params->MasterClock));
}
}
}
else
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F288_FROZE_LOCK,0);
Kt-=10;
}
while((signalType != RANGEOK_288) && (symbolrate_ok) && (Kt>=24));
if(signalType != RANGEOK_288) FE_288_NextSubRange(Params);
}
while(Params->SubRange && signalType != RANGEOK_288 );
return signalType;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -