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 + -
显示快捷键?