📄 stv0399drv.c
字号:
160, 3210,
170, 3020,
180, 2860,
190, 2700,
200, 2600
}
};
static STV0399SignalQuality_LookUp[20][2] = {
10, 15,
20, 21,
30, 27,
40, 33,
50, 39,
60, 45,
70, 51,
80, 57,
90, 63,
100, 69,
110, 75,
120, 81,
130, 87,
140, 93,
150,100,
160,100,
170,100,
180,100,
190,100,
200,100
};
//#endif
typedef enum
{
PLL_X4 = 0, /* PLL by 4 */
PLL_X5 = 1 /* PLL by 5 */
} STV0399PLL_MULTIPLIER_t;
typedef enum
{
VCO_HIGH = 0, /* FASTEST VCO */
VCO_LOW = 1 /* SLOWEST VCO */
} STV0399VCO_t;
CSQPSK_Error_t (*CSDMDPatch[MAX_TUNER_NUM])( CSHDITunerIndex bTunerIndex);
static DWORD g_bTunerLockedNum[MAX_TUNER_NUM]= { 0, 0};
static CSQPSK_Error_t STV0399Patch( CSHDITunerIndex bTunerIndex);
static CSQPSK_Error_t STV0399IQInvertion ( CSHDITunerIndex bTunerIndex);
static int STV0399CheckData( CSHDITunerIndex bTunerIndex, STV0399InternalParams_t *pParams);
static int STV0399GetSymbolRate( CSHDITunerIndex bTunerIndex, int dwMasterClock);
CSQPSK_Error_t STV0399GetSignalInfo( CSHDITunerIndex bTunerIndex, STV0399SignalInfo_t *pInfo, STV0399InternalParams_t *pParams);
static int STV0399GetMclkFreq ( CSHDITunerIndex bTunerIndex, int dwExtClk);
static CSQPSK_Error_t STV0399SetSymbolRate( CSHDITunerIndex bTunerIndex, DWORD dwMasterClock, DWORD dwSymbolRate);
static int STV0399GetErrorCount( CSHDITunerIndex bTunerIndex, STV0399ERRORCOUNTER_t nCounter);
static int STV0399GetSyntFreq( CSHDITunerIndex bTunerIndex, int dwQuartz);
DWORD STV0399GetPLLMultCoeff( CSHDITunerIndex bTunerIndex);
static int STV0399SelectLPF( CSHDITunerIndex bTunerIndex, STV0399InternalParams_t *pParams);
static CSQPSK_Error_t STV0399SetF22Register( CSHDITunerIndex bTunerIndex, int nMClkValue);
long PowOf2(int number);
static STV0399InternalParams_t g_pT_Params[MAX_TUNER_NUM];
static void STV0399HWReset( CSHDITunerIndex bTunerIndex)
{
CSQPSKReset( bTunerIndex);
}
/* +==========================================================================+ */
/* | SOURCE CODE | */
/* +==========================================================================+ */
/* +==========================================================================+ */
/* | Function: 从STV0399读一串数据 | */
/* | Input: 起始寄存器索引号 | */
/* | 指向数据的指针 | */
/* | 待读入数据个数 | */
/* | Output: 读出的数据 | */
/* | Return: 操作成功标志 | */
/* +==========================================================================+ */
static CSQPSK_Error_t STV0399GetRegisters( CSHDITunerIndex bTunerIndex, BYTE bStartReg, PBYTE pbValue, DWORD dwLength )
{
CSQPSK_Error_t nResult= CSQPSK_SUCCESS ;
BYTE bValue;
if ( CSI2CRequestBus_inner( bTunerIndex, CSHDI_TIMEOUT_INFINITY) == CSI2C_SUCCESS )
{
bValue = bStartReg;
if ( CSI2CWriteWithStop ( g_hdlSTV0399I2C[bTunerIndex], &bValue, 1 ) != CSI2C_SUCCESS )
{
CSTRACE( ERROR_LEVEL, "\n[HDI][CS_QPSK][STV0399GetRegisters]:\nGet STV0399 Error");
nResult = CSQPSK_FAILURE;
}
if ( CSI2CReadWithStop (g_hdlSTV0399I2C[bTunerIndex], pbValue, dwLength) != CSI2C_SUCCESS )
nResult = CSQPSK_FAILURE;
CSI2CReleaseBus_inner( bTunerIndex);
}
else
{
nResult = CSQPSK_FAILURE;
}
return nResult;
}
// end STV0399GetRegisters()
static CSQPSK_Error_t STV0399ReadRegisters( CSHDITunerIndex bTunerIndex, BYTE bStartReg, PBYTE pbValue, DWORD dwLength )
{
CSQPSK_Error_t nResult= CSQPSK_SUCCESS ;
BYTE bValue;
bValue = bStartReg;
if ( CSI2CWriteWithStop ( g_hdlSTV0399I2C[bTunerIndex], &bValue, 1 ) != CSI2C_SUCCESS )
{
CSTRACE( ERROR_LEVEL, "\n[HDI][CS_QPSK][STV0399ReadRegisters]:\nGet STV0399 Error");
nResult = CSQPSK_FAILURE;
}
if ( CSI2CReadWithStop (g_hdlSTV0399I2C[bTunerIndex], pbValue, dwLength) != CSI2C_SUCCESS )
nResult = CSQPSK_FAILURE;
return nResult;
}
/* +==========================================================================+ */
/* | Function: 向STV0399写数据 | */
/* | Input: 起始寄存器索引号 | */
/* | 指向数据的指针 | */
/* | 待写入数据个数 | */
/* | Output: 无 | */
/* | Return: 操作成功标志 | */
/* +==========================================================================+ */
static CSQPSK_Error_t STV0399SetRegisters ( CSHDITunerIndex bTunerIndex, BYTE bStartReg, PBYTE pbValue, DWORD dwLength )
{
DWORD ii;
BYTE pbData[256];
CSQPSK_Error_t nResult = CSQPSK_SUCCESS;
if(dwLength >= 256)
return CSQPSK_FAILURE;
if ( CSI2CRequestBus_inner( bTunerIndex, CSHDI_TIMEOUT_INFINITY) == CSI2C_SUCCESS )
{
pbData[0] = bStartReg;
for ( ii=1; ii<(dwLength+1); ii++ )
pbData[ii] = *pbValue++;
nResult = CSI2CWriteWithStop( g_hdlSTV0399I2C[bTunerIndex], pbData, dwLength+1 );
CSI2CReleaseBus_inner( bTunerIndex);
}
else
{
nResult = CSQPSK_FAILURE;
}
return nResult;
}
static CSQPSK_Error_t STV0399WriteRegisters ( CSHDITunerIndex bTunerIndex, BYTE bStartReg, PBYTE pbValue, DWORD dwLength )
{
DWORD ii;
BYTE pbData[256];
CSQPSK_Error_t nResult = CSQPSK_SUCCESS;
if(dwLength >= 256)
return CSQPSK_FAILURE;
pbData[0] = bStartReg;
for ( ii=1; ii<(dwLength+1); ii++ )
pbData[ii] = *pbValue++;
if ( CSI2CWriteWithStop( g_hdlSTV0399I2C[bTunerIndex], pbData, dwLength+1 ) == CSI2C_SUCCESS)
{
nResult = CSQPSK_SUCCESS;
}
else
{
nResult = CSQPSK_FAILURE;
}
return nResult;
}
/* +==========================================================================+ */
/* | Function: 向STV0399写一个字节数据 | */
/* | Input: 起始寄存器索引号 | */
/* | 指向数据的指针 | */
/* | 待写入数据个数 | */
/* | Output: 无 | */
/* | Return: 操作成功标志 | */
/* +==========================================================================+ */
static CSQPSK_Error_t STV0399SetOneRegister ( CSHDITunerIndex bTunerIndex, BYTE bRegIndex, BYTE bRegValue )
{
return STV0399SetRegisters ( bTunerIndex, bRegIndex, &bRegValue, 1);
}
static CSQPSK_Error_t STV0399WriteOneRegister ( CSHDITunerIndex bTunerIndex, BYTE bRegIndex, BYTE bRegValue )
{
return STV0399WriteRegisters ( bTunerIndex, bRegIndex, &bRegValue, 1);
}
/* +==========================================================================+ */
/* | Function: 从STV0399读一个数据 | */
/* | Input: 起始寄存器索引号 | */
/* | 指向数据的指针 | */
/* | 待读入数据个数 | */
/* | Output: 读出的数据 | */
/* | Return: 操作成功标志 | */
/* +==========================================================================+ */
static CSQPSK_Error_t STV0399GetOneRegister ( CSHDITunerIndex bTunerIndex, BYTE bRegIndex, BYTE *bValue )
{
//printf("\n==========Enter STV0399GetOneRegister================");
return STV0399GetRegisters ( bTunerIndex, bRegIndex, bValue, 1);
}
static CSQPSK_Error_t STV0399ReadOneRegister ( CSHDITunerIndex bTunerIndex, BYTE bRegIndex, BYTE *bValue )
{
//printf("\n==========Enter STV0399GetOneRegister================");
return STV0399ReadRegisters ( bTunerIndex, bRegIndex, bValue, 1);
}
/* +==========================================================================+ */
/* | Function: 改写指定寄存器的指定位的数据, 不改变其它位的数据 | */
/* | Input: 寄存器索引号 | */
/* | 数据位MASK | */
/* | 数据位数据 | */
/* | Output: 无 | */
/* | Return: 操作成功标志 | */
/* +==========================================================================+ */
static CSQPSK_Error_t STV0399SetRegisterBits( CSHDITunerIndex bTunerIndex, BYTE bRegIndex, BYTE bMaskValue, BYTE bBitsValue )
{
BYTE bValue;
if ( STV0399GetOneRegister ( bTunerIndex, bRegIndex, &bValue) != CSQPSK_SUCCESS )
return CSQPSK_FAILURE;
bValue &= ~bMaskValue;
bValue |= bBitsValue;
return STV0399SetOneRegister ( bTunerIndex, bRegIndex, bValue);
}
static CSQPSK_Error_t STV0399WriteRegisterBits( CSHDITunerIndex bTunerIndex, BYTE bRegIndex, BYTE bMaskValue, BYTE bBitsValue )
{
BYTE bValue;
if ( STV0399ReadOneRegister ( bTunerIndex, bRegIndex, &bValue) != CSQPSK_SUCCESS )
return CSQPSK_FAILURE;
bValue &= ~bMaskValue;
bValue |= bBitsValue;
return STV0399WriteOneRegister ( bTunerIndex, bRegIndex, bValue);
}
/*****************************************************
**FUNCTION :: STV0399CalcDerotFreq
**ACTION :: Compute Derotator frequency
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: Derotator frequency (KHz)
*****************************************************/
static int STV0399CalcDerotFreq(BYTE derotmsb,BYTE derotlsb, int fm)
{
int dfreq;
int Itmp;
Itmp = (short int)(derotmsb<<8)+derotlsb;
dfreq = (int)(Itmp*(fm/10000L));
dfreq = (int)(dfreq / 65536L);
dfreq *= 10;
return dfreq;
}
/*****************************************************
**FUNCTION :: STV0399GetDerotFreq
**ACTION :: Read current Derotator frequency
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: Derotator frequency (KHz)
*****************************************************/
static int STV0399GetDerotFrequency( CSHDITunerIndex bTunerIndex, int MasterClock)
{
/* Read registers */
BYTE pbRegValue[4];
STV0399GetRegisters ( bTunerIndex, STV0399REG_CFRM, pbRegValue, 2);/* read derotator value */
return STV0399CalcDerotFreq(pbRegValue[0], pbRegValue[1], MasterClock);
}
static int InRange(int x, int y, int z)
{
return ((x<=y && y<=z) || (z<=y && y<=x))?1:0;
}
static CSQPSK_Error_t STV0399GetCNR ( CSHDITunerIndex bTunerIndex, STV0399LookUp_t *pLookup, int *nSNRValue)
{
BYTE pbRegValue[4];
int nNIRValue, nMaxValue, nMinValue, i;
*nSNRValue = 0;
if(STV0399GetOneRegister( bTunerIndex, STV0399REG_VSTATUS, pbRegValue) != CSQPSK_SUCCESS)
return CSQPSK_FAILURE;
if(pbRegValue[0] & STV0399_CFMASK)
{
if((pLookup != NULL) && pLookup->nSize)
{
if(STV0399GetRegisters( bTunerIndex, STV0399REG_NIRH, pbRegValue, 2) != CSQPSK_SUCCESS)
return CSQPSK_FAILURE;
nNIRValue = ((int)pbRegValue[0] << 8) + (int)pbRegValue[1];
nMinValue = 0;
nMaxValue = pLookup->nSize-1;
if(InRange(pLookup->pTable[nMinValue].nRealValue,nNIRValue,pLookup->pTable[nMaxValue].nRealValue))
{
while((nMaxValue-nMinValue)>1)
{
i=(nMaxValue+nMinValue)/2;
if(InRange(pLookup->pTable[nMinValue].nRealValue,nNIRValue,pLookup->pTable[i].nRealValue))
nMaxValue = i;
else
nMinValue = i;
}
*nSNRValue = ((nNIRValue - pLookup->pTable[nMinValue].nRealValue)
* (pLookup->pTable[nMaxValue].nRealValue - pLookup->pTable[nMinValue].nRealValue)
/ (pLookup->pTable[nMaxValue].nRealValue - pLookup->pTable[nMinValue].nRealValue))
+ pLookup->pTable[nMinValue].nRealValue;
}
else
*nSNRValue = 100;
return CSQPSK_SUCCESS;
}
else
return CSQPSK_FAILURE;
}
else
{
return CSQPSK_SUCCESS;
}
}
static CSQPSK_Error_t STV0399GetSignalStrength ( CSHDITunerIndex bTunerIndex, STV0399LookUp_t *pLookup, int *nStrength)
{
BYTE pbRegValue[4];
int nNIRValue, nMaxValue, nMinValue, i;
int nAGCGain = 0;
*nStrength = 0;
if((pLookup != NULL) && pLookup->nSize)
{
if(STV0399GetRegisters( bTunerIndex, STV0399REG_AGC0I, pbRegValue, 3) != CSQPSK_SUCCESS)
return CSQPSK_FAILURE;
nAGCGain = ((int)pbRegValue[0]) * 10 + ((int)pbRegValue[2]) * 5;
nMinValue = 0;
nMaxValue = pLookup->nSize - 1;
if(InRange(pLookup->pTable[nMinValue].nRealValue, nAGCGain,pLookup->pTable[nMaxValue].nRealValue))
{
while((nMaxValue-nMinValue)>1)
{
i=(nMaxValue+nMinValue)/2;
if(InRange(pLookup->pTable[nMinValue].nRealValue,nAGCGain,pLookup->pTable[i].nRealValue))
nMaxValue = i;
else
nMinValue = i;
}
*nStrength = ((nAGCGain - pLookup->pTable[nMinValue].nRealValue)
* (pLookup->pTable[nMaxValue].nRealValue - pLookup->pTable[nMinValue].nRealValue)
/ (pLookup->pTable[nMaxValue].nRealValue - pLookup->pTable[nMinValue].nRealValue))
+ pLookup->pTable[nMinValue].nRealValue;
}
else
*nStrength = 0;
return CSQPSK_SUCCESS;
}
else
return CSQPSK_FAILURE;
}
/*****************************************************
**FUNCTION :: STV0399GetDivRatio
**ACTION :: Retreive the STV0399 synthesizer first divider ratio
**PARAMS IN :: hChip ==> handle to the chip
**PARAMS OUT:: NONE
**RETURN :: Ratio (1..15)
*****************************************************/
static int STV0399GetDivRatio( CSHDITunerIndex bTunerIndex)
{
BYTE bValue;
int nbbitused = 0;
int nbbithigh = 0;
int nRatio = 1;
STV0399GetOneRegister( bTunerIndex, STV0399REG_DIVCTRL, &bValue);
while(((bValue & 0x01) == 0x00) && (nbbitused <= 8))
{
bValue >>= 1;
nbbitused++;
}
while(((bValue & 0x01) == 0x01) && (nbbitused <= 8))
{
bValue >>= 1;
nbbitused++;
nbbithigh++;
}
nRatio = (nbbitused*2)-(nbbithigh-1);
return nRatio;
}
#define N_BYP_MASK 0x40
#define CMD_DIV_MASK 0xE0
#define MINIMUM_GAP 18000 /* Minimum gap size between master clock bHarmonic and tuner frequency (KHz) */
static CSQPSK_Error_t STV0399SetDivRatio ( CSHDITunerIndex bTunerIndex, int nRatio)
{
BYTE bMode;
BYTE bDivider = 0x01;
if ((nRatio & 0x01) == 0x01)
bDivider = 0x03;
bDivider <<= ((nRatio / 2) - 1);
if ( CSI2CRequestBus_inner( bTunerIndex, CSHDI_TIMEOUT_INFINITY) != CSI2C_SUCCESS )
{
return CSQPSK_FAILURE;
}
if(STV0399ReadOneRegister( bTunerIndex, STV0399REG_DIVOUT, &bMode) != CSQPSK_SUCCESS)
{
CSI2CReleaseBus_inner( bTunerIndex);
return CSQPSK_FAILURE;
}
if(STV0399WriteRegisterBits( bTunerIndex, STV0399REG_SYNTCTRL, N_BYP_MASK, 0) != CSQPSK_SUCCESS)/* Synthesizer bypass */
{
CSI2CReleaseBus_inner( bTunerIndex);
return CSQPSK_FAILURE;
}
if(STV0399WriteOneRegister( bTunerIndex, STV0399REG_DIVOUT, 0) != CSQPSK_SUCCESS)/* Divider bypass */
{
CSI2CReleaseBus_inner( bTunerIndex);
return CSQPSK_FAILURE;
}
if(STV0399WriteOneRegister( bTunerIndex, STV0399REG_DIVCTRL, 0) != CSQPSK_SUCCESS)/* Reset divider */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -