📄 drv0299.c
字号:
D0299_SignalType_t Drv0299_CheckTiming(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, D0299_SearchParams_t *Params)
{
U8 locked;
S8 timing;
SystemWaitFor(Params->Ttiming);
locked = STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0299_TLIR);
timing = STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0299_RTF);
if(locked >= 43)
{
if((locked > 48) && ((MAC0299_ABS(timing)) >= 110))
Params->State = E299_ANALOGCARRIER;
else
Params->State = E299_TIMINGOK;
}
else
Params->State = E299_NOTIMING;
return(Params->State);
}
#endif
#ifndef STTUNER_MINIDRIVER
/*----------------------------------------------------
FUNCTION OffsetSymbolRate
ACTION Set actual symbol rate by adding offset in the symbol rate
PARAMS IN offset
PARAMS OUT NONE
RETURN NONE
------------------------------------------------------*/
void FE_299_OffsetSymbolRate(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,S32 Offset)
{
U32 U32Tmp;
S32 tst;
U8 sfrh[3],freq[3];
STTUNER_IOREG_GetContigousRegisters(DeviceMap, IOHandle, R0299_SFRH, 3,sfrh);
freq[2] = sfrh[2] ;
U32Tmp = (sfrh[0] & 0xFF)<<12;
U32Tmp += (sfrh[1] & 0xFF)<<4;
U32Tmp +=(STTUNER_IOREG_FieldExtractVal(sfrh[2], F0299_SYMB_FREQL) & 0x0F);
tst = ((Offset*(S32)U32Tmp) / 524288); /* 2^19 = 524288*/
U32Tmp += tst;
freq[0]= (U32Tmp>>12)&0xFF;
freq[1]= (U32Tmp>>4)&0xFF;
STTUNER_IOREG_SetFieldVal(DeviceMap, F0299_SYMB_FREQL,U32Tmp&0x0F,freq+2);
STTUNER_IOREG_SetContigousRegisters(DeviceMap, IOHandle, R0299_SFRH, freq,3);
}
/*----------------------------------------------------
FUNCTION CenterTimingLoop
ACTION Timing loop centring
PARAMS IN SymbolRate -> Current symbol rate value
MasterClock -> Current master clock frequency
PARAMS OUT NONE
RETURN New symbol rate
------------------------------------------------------*/
long Drv0299_CenterTimingLoop(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, long SymbolRate, long MasterClock)
{
int i;
short int tTiming;
S8 timingOffset;
tTiming = (short int)(Drv0299_CalcTimingTimeConstant(SymbolRate) );
for(i=0;i<5;i++)
{
SystemWaitFor(tTiming);
timingOffset = STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0299_RTF);
if(ABS(timingOffset) >= 20)
{
FE_299_OffsetSymbolRate(DeviceMap,IOHandle,timingOffset);
}
else
{
task_delay(tTiming*(ST_GetClocksPerSecond()/1000));
timingOffset = STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0299_RTF);
/* Check timing offset a second time in case of analog transponders */
if(ABS(timingOffset)<20)
{
SymbolRate = Reg0299_RegGetSymbolRate(DeviceMap, IOHandle);
}
break;
}
}
return(SymbolRate);
}
/*----------------------------------------------------
FUNCTION CheckAgc2
ACTION Check agc2 value
PARAMS IN NbSample -> Number of samples
PARAMS OUT Agc2Value -> Mean of Agc2 values
RETURN E299_NOAGC2 if AGC2 =0 or AGC2 = 32767, E299_AGC2OK otherwise
------------------------------------------------------*/
D0299_SignalType_t Drv0299_CheckAgc2(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, int NbSample,long *Agc2Value)
{
int Agc2Threshold, loop;
long Agc2Limit;
D0299_SignalType_t Agc2Level;
U8 agc[2];
Agc2Threshold = 0;
Agc2Limit = 32767 * (long)NbSample; /* cast added to eliminate compiler warning --SFS */
for (loop = 0; loop < NbSample; loop++)
{
SystemWaitFor(1); /* 1ms delay: settling time */
STTUNER_IOREG_GetContigousRegisters(DeviceMap, IOHandle, R0299_AGC2I1, 2,agc); /* Read AGC2I1 and AGC2I2 registers */
/* use int cast below to eliminate compile warning; why does this work??? (I would think it should be caste to long) --SFS */
*Agc2Value += (int)((agc[0]<<8) + agc[1]);
}
if ( ( *Agc2Value > Agc2Threshold ) && ( *Agc2Value < Agc2Limit ) )
{
Agc2Level = E299_AGC2OK;
*Agc2Value = *Agc2Value / NbSample;
}
else
{
Agc2Level = E299_NOAGC2;
*Agc2Value = 0;
}
return(Agc2Level);
}
/*----------------------------------------------------
--FUNCTION CheckCarrier
--ACTION Check for carrier founded
--PARAMS IN Params => Pointer to SEARCHPARAMS structure
--PARAMS OUT Params->State => Result of the check
--RETURN E299_NOCARRIER carrier not founded, E299_CARRIEROK otherwise
------------------------------------------------------*/
D0299_SignalType_t Drv0299_CheckCarrier(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, D0299_SearchParams_t *Params)
{
SystemWaitFor(Params->Tderot); /* wait for derotator ok */
STTUNER_IOREG_SetField(DeviceMap, IOHandle, F0299_CFD_ALGO, 0);
if ( STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0299_CF) )
Params->State = E299_CARRIEROK;
else
Params->State = E299_NOCARRIER;
return(Params->State);
}
#endif
#ifdef STTUNER_MINIDRIVER
D0299_SignalType_t Drv0299_CheckCarrier(D0299_SearchParams_t *Params)
{
U8 Data = 0;
/**********Delay of 100K Symbols************************/
task_delay((100000/(U32)(Params->SymbolRate/1000))*(ST_GetClocksPerSecond()/1000));
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R0299_CFD, F0299_CFD_ALGO, F0299_CFD_ALGO_L, &Data, 1, FALSE);
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R0299_VSTATUS, F0299_CF, F0299_CF_L, &Data, 1, FALSE);
if(Data == 1)
Params->State = E299_CARRIEROK;
else
Params->State = E299_NOCARRIER;
return(Params->State);
}
#endif
/*----------------------------------------------------
--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)
------------------------------------------------------*/
#ifndef STTUNER_MINIDRIVER
long Drv0299_CarrierWidth(long SymbolRate, long RollOff)
{
return (SymbolRate + (SymbolRate * RollOff)/100);
}
/*----------------------------------------------------
FUNCTION CheckData
ACTION Check for data founded
PARAMS IN Params => Pointer to SEARCHPARAMS structure
PARAMS OUT Params->State => Result of the check
RETURN E299_NODATA data not founded, E299_DATAOK otherwise
------------------------------------------------------*/
D0299_SignalType_t Drv0299_CheckData(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, D0299_SearchParams_t *Params)
{
SystemWaitFor(Params->Tdata); /* Wait for data */
if ( STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0299_LK) )
Params->State = E299_DATAOK;
else
Params->State = E299_NODATA;
return(Params->State);
}
#endif
#ifdef STTUNER_MINIDRIVER
D0299_SignalType_t Drv0299_CheckData(D0299_SearchParams_t *Params)
{
U8 Data;
int i=0, loopcount = 0, timeout = 100;
i = timeout/10;
do{
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R0299_VSTATUS, F0299_LK, F0299_LK_L, &Data, 1, FALSE);
if ( Data == 1)
{
Params->State = E299_DATAOK;
return(Params->State);
}
else
Params->State = E299_NODATA;
task_delay(10*(ST_GetClocksPerSecond()/1000));
++loopcount;
}while((loopcount<= i) && (Params->State !=E299_DATAOK));
return(Params->State);
}
void Drv0299_IQInvertion(void)
{
U8 iq;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R0299_IOCFG, F0299_IQ, F0299_IQ_L, &iq, 1, FALSE);
iq = 0x01 & (~iq);
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R0299_IOCFG, F0299_IQ, F0299_IQ_L, &iq, 1, FALSE);
}
#endif
#ifndef STTUNER_MINIDRIVER
/*----------------------------------------------------
FUNCTION IQInvertion
ACTION Invert I and Q
PARAMS IN NONE
PARAMS OUT NONE
RETURN NONE
------------------------------------------------------*/
void Drv0299_IQInvertion(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
U32 iq;
iq = STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0299_IQ);
STTUNER_IOREG_SetField(DeviceMap, IOHandle, F0299_IQ, 0x01 & (~iq) ); /* inverting the I/Q configuration */
}
/*----------------------------------------------------
FUNCTION IQSet
ACTION Set I and Q
PARAMS IN NONE
PARAMS OUT NONE
RETURN NONE
------------------------------------------------------*/
void Drv0299_IQSet(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 IQMode)
{
STTUNER_IOREG_SetField(DeviceMap, IOHandle, F0299_IQ, IQMode); /* Set the I/Q configuration */
}
#endif
#ifdef STTUNER_MINIDRIVER
void Drv0299_IQSet(U32 IQMode)
{
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R0299_IOCFG, F0299_IQ, F0299_IQ_L, (U8 *)IQMode, 1, FALSE);
}
#endif
#ifndef STTUNER_MINIDRIVER
/*----------------------------------------------------
--FUNCTION CalcTimingTimeConstant
--ACTION Compute the amount of time needed by the timing loop to lock
--PARAMS IN SymbolRate -> symbol rate value
--PARAMS OUT NONE
--RETURN Timing loop time constant (ms)
------------------------------------------------------*/
long Drv0299_CalcTimingTimeConstant(long SymbolRate)
{
return (200000/(SymbolRate/1000));
}
/*----------------------------------------------------
FUNCTION CalcDerotTimeConstant
ACTION Compute the amount of time needed by the Derotator to lock
PARAMS IN SymbolRate -> symbol rate value
PARAMS OUT NONE
RETURN Derotator time constant (ms)
------------------------------------------------------*/
long Drv0299_CalcDerotTimeConstant(long SymbolRate)
{
return (10000/(SymbolRate/1000));
}
/*----------------------------------------------------
FUNCTION CalcDataTimeConstant
ACTION Compute the amount of time needed to capture data
PARAMS IN Er -> Viterbi rror rate
Sn -> viterbi averaging period
To -> viterbi time out
Hy -> viterbi hysteresis
SymbolRate -> symbol rate value
PARAMS OUT NONE
RETURN Data time constant
------------------------------------------------------*/
long Drv0299_CalcDataTimeConstant(int Er, int Sn, int To, int Hy, long SymbolRate, U32 R0299_FECMVal)
{
long Tviterbi = 0;
long TimeOut =0;
long THysteresis = 0;
long PhaseNumberDVB[5] = {2,6,4,6,8};
long PhaseNumberDSS[5] = {2,6,4,6,14};
long averaging[4] = {1024L, 4096L, 16384L, 65536L};
long InnerCode = 1000;
long HigherRate = 1000;
int loop, DSS_Mode;
/* Data capture time (in ms)
-------------------------
This time is due to the Viterbi synchronisation.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -