tda10086drv.c

来自「QPSK Tuner details, for conexant chipset」· C语言 代码 · 共 1,716 行 · 第 1/4 页

C
1,716
字号

   
    bByte=0xC9;//200406
    TDA10086SetOneRegister(bTunerIndex,0x20,bByte);

    bByte=0x56;
    TDA10086SetOneRegister(bTunerIndex,0x31,bByte);

    bByte = 0x60;//200406
    TDA10086SetOneRegister(bTunerIndex,0x58,bByte);
}

void TDA10086SetPLL( CSHDITunerIndex bTunerIndex )
{
	BYTE bByte;
	
	/*	TDA10085_PLLTS	*/
	bByte = 0x2C;
	TDA10086SetOneRegister(bTunerIndex,0x55,bByte);

	/*	TDA10085_PLL1    */
	TDA10086SetOneRegister(bTunerIndex,0x3A,0x0b);
	/*	TDA10085_PLL2   */
	TDA10086SetOneRegister(bTunerIndex,0x3B,0x01);
	/*	TDA10085_PLLTS	*/
	bByte=0x2C & ~0x20;
	TDA10086SetOneRegister(bTunerIndex,0x55,bByte);

	return;
}
long AS_PowOf2(int number)
{
	int i;
	long result=1;

	for(i=0;i<number;i++)
		result*=2;

	return result;
}


void TDA10086InitDemod(CSHDITunerIndex bTunerIndex)
{
	BYTE bVAGCA;
	
//	printf("\ng_dwSymRate=%d   g_dwCurrFreq = %d",g_dwSymRate,g_dwCurrFreq);
	TDA10086SetSymbolRate(bTunerIndex,g_dwSymRate[bTunerIndex]);

	TDA10086WriteRF( bTunerIndex,g_dwCurrFreq[bTunerIndex] );
	
    TDA10086GetOneRegister(bTunerIndex, 0x43, &bVAGCA );
    if(bVAGCA==0)
    {
       	TDA10086SetOneRegister(bTunerIndex,0x41, 0xff);	
   		TDA10086SetOneRegister(bTunerIndex,0x42, 0xff);
    }
	else
	{
	   TDA10086SetOneRegister(bTunerIndex,0x41, 0x4f);	
	}
	
	TDA10086WriteVR(bTunerIndex);
	TDA10086WriteSI(bTunerIndex);
	
	TDA10086WriteNextSearch(bTunerIndex, 0, &g_dwCurrFreq[bTunerIndex], g_dwSymRate[bTunerIndex]);
}

DWORD TDA10086WriteRF(CSHDITunerIndex bTunerIndex,DWORD uFreqWanted)
{
	DWORD uFreqProgTuner;
	long lFreqOffset = 0;
	DWORD	uXinDiv1000;
	BYTE	pWrite[2];
	BYTE	pWrite_sub1,pWrite_sub2;

    uFreqProgTuner=uFreqWanted;
    
    if(g_dwSymRate[bTunerIndex]<11000000)
       uFreqProgTuner+=6000;

//	printf("\n---------uFreqProgTuner = %d-----------",uFreqProgTuner);
	TDA8263SetFrequency(bTunerIndex,uFreqProgTuner);

	lFreqOffset = (long)(uFreqWanted - uFreqProgTuner);

	uXinDiv1000 = TDQX_SYSCLK/1000;

	lFreqOffset <<= 16;
	if (lFreqOffset < 0)
		lFreqOffset -= uXinDiv1000/2;
	else
		lFreqOffset += uXinDiv1000/2;
	lFreqOffset /= (long)uXinDiv1000;

	pWrite[0] = (BYTE)((lFreqOffset & 0x0000FF00)>>8);
	pWrite[1] = (BYTE)(lFreqOffset & 0x000000FF);
	pWrite[0] |= 0x80;

	pWrite_sub1=pWrite[0];
	pWrite_sub2=pWrite[1];
	
//	printf("\nREG[0x3D] = 0x%02x",pWrite_sub1);
//	printf("\nREG[0x3E] = 0x%02x",pWrite_sub2);
	TDA10086SetOneRegister(bTunerIndex,0x3D,pWrite_sub1);
	TDA10086SetOneRegister(bTunerIndex,0x3E,pWrite_sub2);

	lFreqOffset *= uXinDiv1000;
	lFreqOffset /= (long)65536L;

    uFreqProgTuner = (DWORD)(uFreqProgTuner + lFreqOffset);

	if (uFreqProgTuner > AS_UPPER_FREQUENCY_VAL)
        uFreqProgTuner = AS_UPPER_FREQUENCY_VAL;

	return uFreqProgTuner;
}

void TDA10086WriteVR( CSHDITunerIndex bTunerIndex )
{
	TDA10086SetOneRegister(bTunerIndex,TDA10086REG_RATE, 0x08);
}

void TDA10086WriteSI( CSHDITunerIndex bTunerIndex )
{
    BYTE bValue;
    
	TDA10086GetOneRegister(bTunerIndex,TDA10086REG_CONF, &bValue);
	bValue &= ~0xC0;
	TDA10086SetOneRegister(bTunerIndex,TDA10086REG_CONF, bValue);
}

int TDA10086WriteNextSearch(CSHDITunerIndex bTunerIndex, BYTE bMode, DWORD* uRF, DWORD uSR)
{
	static DWORD uCounter = 0x00000001;
	static DWORD uCenterFrequency;
	DWORD	uOffsetFreq;

//	printf("\n--------Enter TDA10086WriteNextSearch %d",bMode);
	if (bMode /*== AS_FREQSEARCH_VAL*/)
	{
		//g_bSearchRange = 6;		/* Frequency Offset ... 3MHz in unit of 500KHz, 6*500KHz = 3MHz -> SearchRange */
		if(g_dwSymRate[bTunerIndex]>8000000)   
			g_bSearchRange[bTunerIndex] = 10;  
		else 
			g_bSearchRange[bTunerIndex] = 8; //for 5M change to 10 hjh 20040609 
		if (uSR > ((DWORD)g_bSearchRange[bTunerIndex]*4347826L))
		{
			uCounter = 0x00000001;
			return 0;
		}
		uOffsetFreq  = uSR + 4348L;
		uOffsetFreq /= 8696L;
		if(uOffsetFreq<500) uOffsetFreq=500;/*hjh chagne Because tuner step 500KHz*/
		uOffsetFreq *= (uCounter >> 1);
		if (uOffsetFreq > ((DWORD)g_bSearchRange[bTunerIndex]*500))
		{
			uCounter = 0x00000001;
			uOffsetFreq = 0;
           	return 0;
		}

		if (uCounter & 0x00000001)
			*uRF = uCenterFrequency + uOffsetFreq;
		else
			*uRF = uCenterFrequency - uOffsetFreq;
		*uRF = TDA10086WriteRF(bTunerIndex,*uRF);
		g_dwLockedFreq[bTunerIndex] = *uRF;
//		printf("\n g_dwLockedFreq = %d", g_dwLockedFreq);
		uCounter++;
	}
	else
	{
		uCounter = 0x02;
		uCenterFrequency = *uRF;
	}
	return 1;
}

DWORD SumProdOf2(int number)
{
	int i;
	DWORD result=1;

	for(i=0;i<number;i++)
		result*=2;

	return result;
}

void TDA10086AlgoStart(CSHDITunerIndex bTunerIndex)
{
	BYTE bByte;
	BYTE bByteVAGCA = AS_AGCRA_DEF;

	TDA10086GetOneRegister(bTunerIndex,0x00,&bByte);
	bByte&=~0x01;
	bByte|=0x00;
	TDA10086SetOneRegister(bTunerIndex,0x00,bByte);
}


BYTE TDA10086AlgoMain(CSHDITunerIndex bTunerIndex, int* pAlgoTimer, DWORD *pRF, DWORD uSR)
{
	long  	lAFC;
	DWORD 	uWait;
	BYTE  	retStatus;
	int		nReturn;

	*pAlgoTimer = TDA10086_ALGO_AGCA_TIMER_VAL;
	*pAlgoTimer += TDA10086_ALGO_AGCCONV_TIMER_VAL;
	*pAlgoTimer += TDA10086AlgoCalcTimer(TDA10086_ALGO_RXSIG_TIMER_VAL, uSR);
	nReturn = CSQPSKSleep(bTunerIndex, (*pAlgoTimer)); /* KDEAN_FIELD_TEST */
	if ( nReturn == CSQPSK_DROPPED )
	{
		return AS_ALGOQUICKEXIT_RET;
	}

	TDA10086ReadSync(bTunerIndex);	/* hjh change */
	
	if(g_tDemodStatus[bTunerIndex].bFrameSync) 
	{
		return AS_ALGOSUCCESS_RET;
	}

	if (g_tDemodStatus[bTunerIndex].bReceiveSignal)
	{
		*pAlgoTimer = TDA10086AlgoCalcTimer(TDA10086_ALGO_LOCK_TIMER_VAL, uSR);
		nReturn = CSQPSKSleep(bTunerIndex, (*pAlgoTimer));	/* KDEAN_FIELD_TEST */
		if ( nReturn == CSQPSK_DROPPED )
		{
			return AS_ALGOQUICKEXIT_RET;
		}
		
		TDA10086ReadSync(bTunerIndex);	/* hjh change */
		if(g_tDemodStatus[bTunerIndex].bFrameSync) 
		{
			return AS_ALGOSUCCESS_RET;
		}
	}

	g_bSearchRange[bTunerIndex]=1;
	if (!g_tDemodStatus[bTunerIndex].bFrameSync && g_bSearchRange[bTunerIndex])
	{
		retStatus=TDA10086WriteNextSearch(bTunerIndex, 1, pRF, uSR);
		if (retStatus == 1)
		{
			TDA10086AlgoStart(bTunerIndex);
			*pAlgoTimer = TDA10086AlgoCalcTimer(TDA10086_ALGO_LOCK_TIMER_VAL, uSR);
			nReturn = CSQPSKSleep(bTunerIndex,(*pAlgoTimer));	/* KDEAN_FIELD_TEST */
			if ( nReturn == CSQPSK_DROPPED )
			{
				return AS_ALGOQUICKEXIT_RET;
			}
			TDA10086ReadSync(bTunerIndex);
     		if(g_tDemodStatus[bTunerIndex].bFrameSync) /* hjh change */
    		 {
         		g_dwCurrFreq[bTunerIndex]=g_dwLockedFreq[bTunerIndex];
         		return AS_ALGOSUCCESS_RET;
     		}
        }
        else
        {
        	/* All range is searched to result in failure. let's stop searching */
        	return AS_ALGOFAILED_RET;
        }
    }   
}

int TDA10086AlgoCalcTimer(DWORD dwNbSymbol, DWORD dwSR)
{	
	dwNbSymbol += TDA10086_ALGO_RAUTO_TIMER_VAL;
	dwNbSymbol *= 1000;
	dwNbSymbol += dwSR/2;
	dwNbSymbol /= dwSR;
	
	if(dwNbSymbol<100)
	{
		dwNbSymbol = 100;
	}
	return (int)dwNbSymbol;
}


BYTE TDA10086ReadSync(CSHDITunerIndex bTunerIndex)
{
	BYTE	bSyncByte;

	TDA10086GetOneRegister(bTunerIndex,0x0E,&bSyncByte);

	g_tDemodStatus[bTunerIndex].bReceiveSignal 	= (bSyncByte & 0x01)?1:0;
	g_tDemodStatus[bTunerIndex].bCarLock			= (bSyncByte & 0x02)?1:0;
	g_tDemodStatus[bTunerIndex].bFrameSync		= (bSyncByte & 0x08)?1:0;
	g_tDemodStatus[bTunerIndex].bFel				= (bSyncByte & 0x10)?1:0;

	return(bSyncByte);
}

CSQPSK_Error_t TDA10086SetSymbolRate (CSHDITunerIndex bTunerIndex, DWORD dwSymbolRate)
{
	BYTE bRegValue;
	BYTE bConfReg;
	BYTE bBypass = 0;
	BYTE pbBaudReg[4];
	DWORD dwCutOff;
	DWORD dwTemp;
	DWORD dwFreqSymbInv;
	double fFreqSymb;
	double fSysClk;
	DWORD dwSymbolRateDivider = 0;
//	printf("\nTDQX_SYSCLK=%d  dwSymbolRate=%d\n",TDQX_SYSCLK,dwSymbolRate);
		
	if(0 == dwSymbolRate)
		return CSQPSK_FAILURE;	// 参数错误, 防止除0出错,退出
	if(TDA10086GetOneRegister(bTunerIndex,TDA10086REG_FTUN_MSB, &bRegValue) != CSQPSK_SUCCESS)
		return CSQPSK_FAILURE;
	bRegValue |= 0x80;
	if(TDA10086SetOneRegister(bTunerIndex,TDA10086REG_FTUN_MSB, bRegValue) != CSQPSK_SUCCESS)
		return CSQPSK_FAILURE;
	dwCutOff = (TDQX_SYSCLK * 10) / dwSymbolRate;
	
	bConfReg = 0x84;

	if (dwCutOff < 720)
		bConfReg = 0x04;
	if (dwCutOff < 480)
		bConfReg = 0x83;
	if (dwCutOff < 360)
		bConfReg = 0x03;
	if (dwCutOff < 240)
		bConfReg = 0x82;
	if (dwCutOff < 180)
		bConfReg = 0x02;
	if (dwCutOff < 120)
		bConfReg = 0x81;
	if (dwCutOff <  90)
		bConfReg = 0x01;
	if (dwCutOff <  60)
		bConfReg = 0x80;
	if (dwCutOff <  45)
		bConfReg = 0x00;
	if (dwCutOff <  30)
    {
		bConfReg = 0x00;
		bBypass = 1;
		TDA10086SetOneRegister(bTunerIndex,0x37, 0x63);	
		TDA10086SetOneRegister(bTunerIndex,0x42, 0x4F);
    }
    else
    {
    	TDA10086SetOneRegister(bTunerIndex,0x37, 0x43);	
		TDA10086SetOneRegister(bTunerIndex,0x42, 0x43);    	
    }
	if(TDA10086SetOneRegister(bTunerIndex,TDA10086REG_FCONF, bConfReg) != CSQPSK_SUCCESS)
		return CSQPSK_FAILURE;
		
	if (bBypass == 1)
	{
		if(TDA10086GetOneRegister(bTunerIndex,TDA10086REG_ADCONF, &bRegValue) != CSQPSK_SUCCESS)
			return CSQPSK_FAILURE;
		bRegValue |= 0x08;
		if(TDA10086SetOneRegister(bTunerIndex,TDA10086REG_ADCONF, bRegValue) != CSQPSK_SUCCESS)
			return CSQPSK_FAILURE;
	}
	else
	{
		if(TDA10086GetOneRegister(bTunerIndex,TDA10086REG_ADCONF, &bRegValue) != CSQPSK_SUCCESS)
			return CSQPSK_FAILURE;
		bRegValue &= ~0x08;
		if(TDA10086SetOneRegister(bTunerIndex,TDA10086REG_ADCONF, bRegValue) != CSQPSK_SUCCESS)
			return CSQPSK_FAILURE;
    	}
	if(TDA10086GetOneRegister(bTunerIndex,TDA10086REG_FCONF, &bRegValue) != CSQPSK_SUCCESS)
		return CSQPSK_FAILURE;
	bRegValue &= 0x07;
	dwTemp = 1 << (DWORD)bRegValue;
	dwFreqSymbInv = TDQX_SYSCLK * 32;
	dwFreqSymbInv /= (dwTemp * dwSymbolRate);
	fFreqSymb = (double)(dwSymbolRate * dwTemp);
	fFreqSymb /= (double)TDQX_SYSCLK;
	fFreqSymb *= 2097152.0;
	dwTemp = (DWORD)(fFreqSymb + 0.5);	
	dwSymbolRateDivider = dwTemp + 0x1000000;
	pbBaudReg[0] = (BYTE)(dwSymbolRateDivider & 0xFF);
	pbBaudReg[1] = (BYTE)((dwSymbolRateDivider >> 8) & 0xFF);
	pbBaudReg[2] = (BYTE)((dwSymbolRateDivider >> 16) & 0xFF);
	pbBaudReg[3] = (BYTE)(dwFreqSymbInv & 0xFF);
	
//	printf("mytest\nReg %x %x %x %x", pbBaudReg[0], pbBaudReg[1], pbBaudReg[2], pbBaudReg[3]);

	return TDA10086SetRegisters(bTunerIndex, TDA10086REG_BDR_LSB, pbBaudReg, 4);
	
}


CSQPSK_Error_t TDA10086CheckLockStatus(CSHDITunerIndex bTunerIndex, int *pnLockStatus )
{
	BYTE bSyncByte;
	int ErrorCode;
	
	ErrorCode = TDA10086GetOneRegister( bTunerIndex, 0x0E, &bSyncByte );
	if ( ErrorCode != CSQPSK_SUCCESS )
	{
		return ErrorCode;
	}
	
	if(bSyncByte & 0x10)
	{
		*pnLockStatus = TRUE;
	}
	else
	{
		*pnLockStatus = FALSE;
	}
	return CSQPSK_SUCCESS;
}

DWORD TDA10086GetFineFreq( CSHDITunerIndex bTunerIndex )
{
	return (g_dwCurrFreq[bTunerIndex]+500)/1000;
}

CSQPSK_Error_t TDA10086GetSignalBER( CSHDITunerIndex bTunerIndex, DWORD *pdwBer  )
{
	return CSQPSK_SUCCESS;	
}


⌨️ 快捷键说明

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