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

📄 drv0288.c

📁 st7710的tuner标准驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
{
	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 + -