⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driv0299.c

📁 stv0299资料
💻 C
📖 第 1 页 / 共 4 页
字号:
#define  ENABLE_CENTRE_TIMING

/* #define  ENABLE_DEBUG_PRINT_LOCAL */
#define  SYNCHRONISE_WITH_TUNER_TASK_STATE

/*
--               =================================================
--               |||  STV 0299 evaluation software             |||
--               |||  Version 1.1   dated  Dec 1999			   |||
--               |||  Authors : Jean-Yves COUET				   |||
-- 	             |||          : Mariano BONA                   |||
--				 |||		  : Ardisson Stephane			   |||
--               |||  SGS-THOMSON Video application Lab.       |||
--               =================================================
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "st_tuner.h"  /* Enabling STAPI environment */
#include "vdbase.h" 


#if (HOST > 1000)
	#include "panel_u.h"
	#include "i2c.h"
    #include "System.h"
    #include "ReportP.h"
    #include "ScanP.h"
    #include "bmarkp.h"
#endif


#include "fereport.h"

/* 
 * VICKY - 100200 - added two state variables to break from the search loop,
 * so that during the channel search, we will have faster response.
 */
extern   signed char    cTransponderIndex2bRetrieved;
extern   signed short int  asSymbolRateOffset [ MAX_NO_OF_TRANSPONDERS ];
extern   int               iCurFsRegOffset;

extern   int   iCurTunerTaskState,
               iSavedTunerTaskState;

SEARCHPARAMS Params;
SEARCHRESULT Result;

/*==============================================================================
--==============================================================================
--
--                      MESSAGES ROUTINES
--
--------------------------------------------------------------------------------
--								   SendDebugMessage(int, long, long)
--
--				This routine selects the message to insert in
--          the execution report (if required)
--
------------------------------------------------------------------------------*/
void SendDebugMessage(int _MessageNumber, long _Value1, long _Value2)
{
	#if( HOST > 1000 )
    	ReportInsertMessage(_MessageNumber, _Value1, _Value2)  ;
	#endif
}


#if( HOST < 1000 )
void SystemWaitFor(int ms)
{
   DEMOD_Delay(ms);
}
#endif

/*****************************************************
--FUNCTION	::	WaitTuner
--ACTION	::	Wait for tuner locked
--PARAMS IN	::	TimeOut	->	Maximum waiting time (in ms) 
--PARAMS OUT::	NONE
--RETURN	::	NONE
--***************************************************/
void WaitTuner(int TimeOut)
{
	int Time=0;
	int TunerLocked = FALSE;
	
	while(!TunerLocked && (Time<TimeOut))
	{
		SystemWaitFor(1);
		TunerLocked = TunerGetTunerLock();
		Time++;
	}
	Time--;
}

/****************************************************
--FUNCTION	::	CheckAgc1
--ACTION	::	Check agc1 value
--PARAMS IN	::	pParams	->	Pointer to SEARCHPARAMS structure
--PARAMS OUT::	pParams->State is modified 
--RETURN	::	NOAGC1 if AGC1=-128, AGC1SATURATION
--				if AGC1=127, AGC1OK otherwise
--**************************************************/
SIGNALTYPE CheckAgc1(SEARCHPARAMS *pParams)
{
	int AGC1Value;
	int Agc1Threshold = -128; 
	
	AGC1Value = RegGetField(AGCINTEGRATORVALUE);
	
	if (AGC1Value == Agc1Threshold)
		pParams->State = NOAGC1;
	else if(AGC1Value == 127)
		pParams->State = AGC1SATURATION;
	else
		pParams->State = AGC1OK;  

   REPORT_PRINT ( ( FE_MSG_AGC1_CHECK, AGC1Value, pParams -> State, 0 ) );

	return pParams->State;
}

/*****************************************************
--FUNCTION	::	CheckTiming
--ACTION	::	Check for timing locked
--PARAMS IN	::	pParams->Ttiming	=>	Time to wait for timing loop locked
--PARAMS OUT::	pParams->State		=>	result of the check
--RETURN	::	NOTIMING if timing not locked, TIMINGOK otherwise
--***************************************************/
SIGNALTYPE CheckTiming(SEARCHPARAMS *pParams)
{
	int locked,
		timing,
		TimingFreq;
		
	unsigned char Sr[3];
		
	SystemWaitFor(pParams->Ttiming);     
	locked=RegGetField(TLIR);
	timing=abs(RegGetField(RTF));
	if(locked >= 43)
	{
   /* VICKY - 030300 - modified the timing check only based on lock value */
#if   0
		if((locked > 48) && (timing >= 110))
			pParams->State = ANALOGCARRIER; 
		else 
#else
		if(locked > 48)
#endif
			pParams->State = TIMINGOK;   
	}
	else
		pParams->State = NOTIMING; 	

   REPORT_PRINT ( ( FE_MSG_TIMING_CHECK, locked, pParams -> State, 0 ) );

	return pParams->State;
}


/*****************************************************
--FUNCTION	::	CheckCarrier
--ACTION	::	Check for carrier founded
--PARAMS IN	::	pParams		=>	Pointer to SEARCHPARAMS structure
--PARAMS OUT::	pParams->State	=> Result of the check
--RETURN	::	NOCARRIER carrier not founded, CARRIEROK otherwise
--***************************************************/
SIGNALTYPE CheckCarrier(SEARCHPARAMS *pParams)
{
	SystemWaitFor(pParams->Tderot);						/*	wait for derotator ok	*/    
	RegSetField(CFD_ALGO,0);
	
	if (RegGetField(CF))
		pParams->State = CARRIEROK;
	else
		pParams->State = NOCARRIER;
		
	return pParams->State;
}


/*****************************************************
--FUNCTION	::	CheckData
--ACTION	::	Check for data founded
--PARAMS IN	::	pParams		=>	Pointer to SEARCHPARAMS structure    
--PARAMS OUT::	pParams->State	=> Result of the check
--RETURN	::	NODATA data not founded, DATAOK otherwise
--***************************************************/
SIGNALTYPE CheckData(SEARCHPARAMS *pParams)
{
	SystemWaitFor(pParams->Tdata);					/*	Wait for data	*/    

	if (RegGetField(LK))
		pParams->State = DATAOK;
	else
		pParams->State = NODATA;
		
	return pParams->State;
}

/*****************************************************
--FUNCTION	::	IQInvertion
--ACTION	::	Invert I and Q
--PARAMS IN	::	NONE
--PARAMS OUT::	NONE
--RETURN	::	NONE
--***************************************************/
void IQInvertion(void)
{		
	RegSetField(IQ,0x01 & (~RegGetField(IQ)));	/* inverting the I/Q configuration */
}

/*****************************************************
--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 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 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 CalcDataTimeConstant(int Er, int Sn,int To,int Hy,long SymbolRate)
{
	long	Tviterbi = 0,
			TimeOut	=0,
			THysteresis	= 0,
			PhaseNumber[5] = {2,6,4,6,8},
		 	averaging[4] = {1024L,4096L,16384L,65536L},
		 	InnerCode = 1000,
		 	HigherRate = 1000;
		 	
	int 	i;
		 	
	/*	=======================================================================
	-- 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.	*/
	for(i=0;i<5;i++)
	{
		if (((Er >> 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 7/8	*/
					InnerCode = 1143;	/* 1.143 */
				break;
			}
			
			Tviterbi +=(int)((PhaseNumber[i]*averaging[Sn]*InnerCode)/SymbolRate);
			
			if(HigherRate < InnerCode) 
				HigherRate = InnerCode;
		}
	}
	
	/*	  time out calculation (TimeOut)
	--    ------------------------------
	--    This value indicates the maximum duration of the synchro word research.	*/
	TimeOut   = (int)((HigherRate * 16384L * (To + 1))/(2*SymbolRate));
	
	/*    Hysteresis duration (Hysteresis)
	--    ------------------------------	*/
	THysteresis = (int)((HigherRate * 26112L * (Hy +1))/(2*SymbolRate));	/*	26112= 16*204*8 bits  */ 
	
	/* a guard time of 1 mS is added */
	return (1 + Tviterbi + TimeOut + THysteresis);
}

/*****************************************************
--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 CarrierWidth(long SymbolRate, long RollOff)
{
	return (SymbolRate  + (SymbolRate*RollOff)/100);
}


/*****************************************************
--FUNCTION	::	InitParams
--ACTION	::	Set Params fields that are never changed during search algorithm   
--PARAMS IN	::	NONE
--PARAMS OUT::	NONE
--RETURN	::	NONE
--***************************************************/
void InitParams(void)
{
	int		stdby,dirclk,k,m,p,
			m1,betaagc1,
			agc2coef,MasterClock;
			
	/*	Read registers (in burst mode)	*/
	RegGetRegisters(R_RCR,2);		/*	Read RCR and MCR registers	*/
	RegGetOneRegister(R_AGC1C);
	RegGetRegisters(R_AGC1R,2);		/*	Read AGC1R and AGC2O registers */
	
	/*	Get fields values	*/
	stdby=FieldGetVal(STDBY);
	dirclk=FieldGetVal(DIRCLK); 
	k=FieldGetVal(K);   
	m=FieldGetVal(M);   
	p=FieldGetVal(P);
	m1=FieldGetVal(AGC1_REF);
	betaagc1=FieldGetVal(BETA_AGC1);   
	agc2coef=FieldGetVal(AGC2COEF);
	
	/*	Initial calculations	*/   
	MasterClock = CalcMasterClkFrequency(stdby,dirclk,k,m,p);
	Params.Tagc1 = CalcAGC1TimeConstant(m1,MasterClock,betaagc1)/20L;
	Params.Tagc2 = CalcAGC2TimeConstant(agc2coef,m1,MasterClock)/1000000L;
	Params.MasterClock = MasterClock;
	Params.Mclk = MasterClock/65536L;
	Params.RollOff = RegGetRollOff();

}

/*****************************************************
--FUNCTION	::	InitSearch
--ACTION	::	Set Params fields that are used by the search algorithm   
--PARAMS IN	::	Frequency	=>	Frequency used to start zig zag 
--				SymbolRate	=>	searched symbol rate
--				SearchRange =>	Range of the search
--				DerotStep	=>	Size of derotator's steps used in the carrier search (in per thousand of symbol frequency)
--				Mode		=>	Search context (SCAN or SEARCH)
--PARAMS OUT::	NONE
--RETURN	::	NONE
--***************************************************/
void InitSearch(int Frequency, int SymbolRate, int SearchRange, int DerotStep, SCANMODE Mode)
{
	TUNER_PROP Tnr;
	
	Params.BaseFreq = Frequency;	
	Params.SymbolRate = SymbolRate;
	Params.SearchRange = SearchRange;
	Params.DerotPercent = DerotStep;
	TunerGetProperties(&Tnr);
	Params.TunerStep = Tnr.StepSize;
	Params.TunerBW = TunerSelectBandwidth(CarrierWidth(SymbolRate,Params.RollOff)/1000 + 3000)*1000;
	Params.TunerIF = Tnr.IF;
	Params.ScanMode = Mode;
	
	Result.SignalType = NOAGC1;
	Result.Frequency = 0;
	Result.SymbolRate = 0;
}

/*****************************************************
--FUNCTION	::	SearchTiming
--ACTION	::	Perform an Fs/2 zig zag to found timing
--PARAMS IN	::	NONE
--PARAMS OUT::	NONE
--RETURN	::	NOTIMING if no valid timing had been found, TIMINGOK otherwise
--***************************************************/
SIGNALTYPE SearchTiming(SEARCHPARAMS *pParams, SEARCHRESULT *pResult)
{
	short int	DerotStep,
				DerotFreq = 0,
				DerotLimit,
				 LastDerotFreq = 0,
				NextLoop = 3;
	int 	index = 0;
			
	pParams->State = NOTIMING;

	/* timing loop computation & symbol rate optimisation	*/
	DerotLimit = (pParams->SubRange/2L)/pParams->Mclk;
	DerotStep = (pParams->SymbolRate/2L)/pParams->Mclk;

	do
	{
		#if (HOST > 1000)  
			ReportInsertMessage(SEARCHOFFSET,DerotFreq,pParams->Mclk);  
		#endif
		
      REPORT_PRINT ( ( FE_MSG_TIMING_SEARCH, DerotFreq, DerotStep, DerotLimit ) );

		if(CheckTiming(pParams)!=TIMINGOK)
		{
			index++;
			#if 1 /* LP 101100 */
			 LastDerotFreq = DerotFreq;
			 #endif
			DerotFreq += index*pParams->Direction*DerotStep;	/*	Compute the next derotator position for the zig zag	*/    
			

			if(ABS(DerotFreq) > DerotLimit)
				NextLoop--;
			
			if(NextLoop)
			{
				FieldSetVal(DEROTATORFREQUENCYMSB,MSB(DerotFreq));
				FieldSetVal(DEROTATORFREQUENCYLSB,LSB(DerotFreq));   
				RegSetRegisters(R_CFRM,2); 							/*	Set the derotator frequency	*/
			}
		}
		else
		{
			pResult->SymbolRate = pParams->SymbolRate;
		}
		
		pParams->Direction = -pParams->Direction;			/*	Change the zigzag direction	*/    
	}
#ifdef   SYNCHRONISE_WITH_TUNER_TASK_STATE
    while((pParams->State!=TIMINGOK) && NextLoop && iCurTunerTaskState == iSavedTunerTaskState );
#else
    while((pParams->State!=TIMINGOK) && NextLoop );
#endif
	
	if(pParams->State == TIMINGOK)
	{
		RegGetRegisters(R_CFRM,2); 								/*	Get the derotator frequency	*/ 
		pParams->DerotFreq = (short int) MAKEWORD(FieldGetVal(DEROTATORFREQUENCYMSB),FieldGetVal(DEROTATORFREQUENCYLSB));
	}
	#if 1	/* LP on 101100 */ 
	 else    {        pParams->DerotFreq = LastDerotFreq;    }	#endif

	return pParams->State;
}

/*****************************************************
--FUNCTION	::	SearchCarrier
--ACTION	::	Search a QPSK carrier with the derotator
--PARAMS IN	::	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -