📄 drv_nim_qpsk.c
字号:
double SpiBias;
/* REG INITIALISZE */
for ( i = 0; i < 70; i++ ){
if(FALSE==DRV_NIM_QPSK_SetRegister(i, InitRegs724[i]))
return(FALSE);
}
switch( QpskDFRatio ){
case 8: Regs724[64] = 8; break;
case 4: Regs724[64] = 15; break;
case 2: Regs724[64] = 35; break;
default: Regs724[64] = 50; break;
}
Regs724[65] = 0;
Regs724[19] = (UI8)CalcApr19();
DFRatio = 1.0/ QpskDFRatio;
if ( QpskSymbolRate >= 20000 ){
Regs724[25] = 0x0;
} else {
if((QpskSymbolRate >= 10000 ) && ( QpskSymbolRate < 20000 ) ){
Regs724[25] = 0x1;
} else {
if(( QpskSymbolRate >= 5000 ) && ( QpskSymbolRate < 10000 ) ){
Regs724[25] = 0x2;
}else{
Regs724[25] = 0x3;
}
}
}
Regs724[25] |= 0x04 ; /* Set DC offset */
Regs724[42] = (UI8)CalcValue42(QpskSymbolRate, QpskFsamp , DFRatio ); /* Clock BIAS Calc */
Temp = ( unsigned int )( ( ( double)QpskFsamp * DFRatio * 134217728.0 / ( QpskSymbolRate/1000.0) ) + 0.5 );
Regs724[49] = (UI8)( Temp & 0xff );
Regs724[50] = (UI8)(( Temp >> 8 ) & 0xff );
Regs724[51] = (UI8)(( Temp >> 16 ) & 0xff );
Regs724[52] = (UI8)(( Temp >> 24 ) & 0x7f );
if(QpskSymbolRate >= 15000){
ClkSwpPram=CLK_SWEEP_RATE_PRM_HIGH;
ClkLimPram=CLK_SWEEP_LIMIT_PRM;
}
else{
if((QpskSymbolRate >= 5000)&&(QpskSymbolRate < 15000)){
ClkSwpPram=CLK_SWEEP_RATE_PRM_HIGH;
ClkLimPram=CLK_SWEEP_LIMIT_PRM;
}
else{
if((QpskSymbolRate >= 4000)&&(QpskSymbolRate < 5000)){
ClkSwpPram=CLK_SWEEP_RATE_PRM_HIGH;
ClkLimPram=CLK_SWEEP_LIMIT_PRM;
}
else{
ClkSwpPram=CLK_SWEEP_RATE_PRM_LOW;
ClkLimPram=CLK_SWEEP_LIMIT_PRM;
}
}
}
ClkSwr = (((ClkSwpPram*(QpskSymbolRate/1000)) / ( QpskFsamp * DFRatio )) + 0.5 );
Regs724[43] = (UI8)((UI32)ClkSwr & 0xff);
/* Regs724[44] = 0x44; ?????????????? */
Regs724[44] = (UI8)(((UI32)ClkSwr >> 8 ) & 0xff);
ClkUswl = (double)( ((ClkLimPram * QpskSymbolRate / QpskFsamp )/ DFRatio) + 0.5 );
ClkLswl = -1.0 * ClkUswl;
Regs724[45] = (UI8)( (UI32)ClkUswl & 0xff);
Regs724[46] = (UI8)( ((UI32)ClkUswl >> 8 ) & 0xff);
Regs724[47] = (UI8)( ((UI32)ClkLswl + 65536) & 0xff);
Regs724[48] = (UI8)((((UI32)ClkLswl + 65536) & 0xff00) >> 8 ) ;
Regs724[53] = 0x39 ; /* Sweep active */
Regs724[28] = (UI8)CalcValue28(QpskSymbolRate,QpskFsamp);
/* Set CarSweepRate! */
if ( QpskSymbolRate >= 15000 ){
CarSwr = QpskSymbolRate * CARRIER_SWEEP_RATE_HIGH; /* ~15000 = 8000 */
}
else if((QpskSymbolRate <15000) && (QpskSymbolRate >= 7500)){
CarSwr = QpskSymbolRate * CARRIER_SWEEP_RATE_MID; /* 7500~14999 = 2000 */
}
else if((QpskSymbolRate <7500 ) && (QpskSymbolRate >= 3500)){
CarSwr = QpskSymbolRate * CARRIER_SWEEP_RATE_LOW; /* 3500~7499 = 1000 */
}
else if((QpskSymbolRate < 3500 ) && (QpskSymbolRate > 2000)){
CarSwr = QpskSymbolRate * CARRIER_SWEEP_RATE_LOW1; /* 2001~3499 = 800 */
}
else{
CarSwr = (0.33 * QpskSymbolRate * QpskSymbolRate - 195 * QpskSymbolRate + 115000); /* ~2001 */
}
CarSwr = ( ( 17.18* CarSwr / ( QpskFsamp * QpskSymbolRate ) ) + 0.5 ) ;
Regs724[32] = (UI8)( (I32)CarSwr & 0xff);
Regs724[33] = (UI8)(((I32)CarSwr & 0xff00 ) >> 8);
CarUSwl = ( ( 65.536 * QpskCarSweepLim / QpskFsamp ) + 0.5 ) ;
CarLSwl = -1.0 * CarUSwl ;
Regs724[34] = (UI8)( (I32)CarUSwl & 0xff);
Regs724[35] = (UI8)(( (I32)CarUSwl & 0xff00 ) >> 8);
Regs724[36] = (UI8)(( (I32)CarLSwl + 16777216 ) & 0xff ) ;
Regs724[37] = (UI8)((((I32)CarLSwl + 16777216 ) & 0xff00 ) >> 8 ) ;
Regs724[38] = 0;
Regs724[39] = 0;
Regs724[40] = 0;
Regs724[41] = 0x65 ;
/* PLL configuration */
PLLS = PLLConst[17].PLLS;
PLLN = PLLConst[17].PLLN;
PLLT = PLLConst[17].PLLT;
PLLM = PLLConst[17].PLLM;
for(i=0;i<17;i++){
if ( PLLConstantFs[i] == QpskFsamp ){
PLLS = PLLConst[i].PLLS;
PLLN = PLLConst[i].PLLN;
PLLT = PLLConst[i].PLLT;
PLLM = PLLConst[i].PLLM;
break;
}
}
Regs724[0] = (UI8)(0x80 | ( PLLN & 0x3f )) ;
Regs724[1] = (UI8)(PLLS & 0x3f);
Regs724[2] = (UI8)(PLLT & 0x1f); /* DVB/QPSK IMQ = 0 */
switch(QpskViterbiRate){
case DRV_NIM_QPSK_VITERBI_AUTO:
Regs724[3] = 0x60; /* Viterbi AUTO */
Regs724[15] = 0x40; /* Bit6:Automatic Code Rate */
SpiNumber = StVCR[6].SpiNum;
SpiDen = StVCR[6].SpiDen;
break;
case DRV_NIM_QPSK_VITERBI_1_2:
Regs724[3] = 0x00; /* Viterbi Rate 1/2 */
Regs724[15] = 0x00; /* Bit6:Code Rate determined by VCR[2:0] */
SpiNumber = StVCR[0].SpiNum;
SpiDen = StVCR[0].SpiDen;
break;
case DRV_NIM_QPSK_VITERBI_2_3:
Regs724[3] = 0x20; /* Viterbi Rate 2/3 */
Regs724[15] = 0x00; /* Bit6:Code Rate determined by VCR[2:0] */
SpiNumber = StVCR[1].SpiNum;
SpiDen = StVCR[1].SpiDen;
break;
case DRV_NIM_QPSK_VITERBI_3_4:
Regs724[3] = 0x40; /* Viterbi Rate 3/4 */
Regs724[15] = 0x00; /* Bit6:Code Rate determined by VCR[2:0] */
SpiNumber = StVCR[2].SpiNum;
SpiDen = StVCR[2].SpiDen;
break;
case DRV_NIM_QPSK_VITERBI_5_6:
Regs724[3] = 0x60; /* Viterbi Rate 5/6 */
Regs724[15] = 0x00; /* Bit6:Code Rate determined by VCR[2:0] */
SpiNumber = StVCR[3].SpiNum;
SpiDen = StVCR[3].SpiDen;
break;
case DRV_NIM_QPSK_VITERBI_6_7:
Regs724[3] = 0x80; /* Viterbi Rate 6/7 */
Regs724[15] = 0x00; /* Bit6:Code Rate determined by VCR[2:0] */
SpiNumber = StVCR[4].SpiNum;
SpiDen = StVCR[4].SpiDen;
break;
case DRV_NIM_QPSK_VITERBI_7_8:
Regs724[3] = 0xa0; /* Viterbi Rate 7/8 */
Regs724[15] = 0x00; /* Bit6:Code Rate determined by VCR[2:0] */
SpiNumber = StVCR[5].SpiNum;
SpiDen = StVCR[5].SpiDen;
break;
}
Regs724[15]|= 0x08; /* Bit3:IMQ_EN Symbol format automatically determined */
Regs724[15]|= 0x02; /* Bit0.1: Mismatching bits */
Regs724[3] = Regs724[3] | ( 1<<3 ) | (UI8)( PLLM & 0x3 ); /* TEI=0 */
Regs724[3] = Regs724[3] | 0x10; /* TEI=1 */
/* Set SPI_M(Group 4 - APR 62) */
Regs724[62] &= 0xe1; /* SPI_M Clear */
TempData = SpiDen << 1;
Regs724[62] |= TempData;
/* Set SPI_M(Group 4 - APR 63) */
Regs724[63] &= 0xf0; /* SPI_N clear */
Regs724[63] |= SpiNumber; /* SPI_N Set */
/* nim_* Set SPI_Bais(Group 4 - APR 66,67,68) */
/* 2^24 * Spi_numerator * Fsymbol / Fsample * Spi_Denominator */
SpiBias = 16777.216 * SpiNumber * QpskSymbolRate / (QpskFsamp * SpiDen);
Regs724[66] = (UI8)(( (I32)SpiBias + 16777216 ) & 0xff ) ;
Regs724[67] = (UI8)((((I32)SpiBias + 16777216 ) & 0xff00 ) >> 8 ) ;
Regs724[68] = (UI8)((((I32)SpiBias + 16777216 ) & 0x7f0000 ) >> 16 ) ;
Regs724[31] = 0xA0; /* SPI Mode ON */
/* send to nim device */
for ( i = 0; i <= 55; i++ ){
if(FALSE==DRV_NIM_QPSK_SetRegister(i, Regs724[i]))
return(FALSE);
}
for ( i = 62; i <= 69; i++ ){
if(FALSE==DRV_NIM_QPSK_SetRegister(i, Regs724[i]))
return(FALSE);
}
return(TRUE);
}
/*****************************************************************
*
* Function Name
* QpskFreqValidRangeCheck
*
* Prototype
* static BOOL QpskFreqValidRangeCheck(void)
*
* Inputs
* None
*
* Outputs
* None
*
* Return Codes
* TRUE : TRUE
* FALSE : TUNER re-setting
*
* Description
* This function a get frequency deviation value.
*
*****************************************************************/
static BOOL QpskFreqValidRangeCheck(void)
{
int FreqDeviation;
int IFValue;
int IFWorkValue;
int FreqValue;
UI8 TunerData[4];
IFValue=DRV_NIM_TUNER_InterFrequency; /* The baing current frequency acquisition */
FreqDeviation = QpskGetFreqDeviation(); /* The deviation frequency acquisition */
if(FreqDeviation < 0){
/* Gap confirmation of a minus direction */
FreqValue= ~FreqDeviation;
if(FreqValue >= FREQ_VALID_RANGE){ /* There is need of frequency amendment? */
IFValue+=FreqValue; /* Frequency amendment */
IFValue=(IFValue / 125) * 125;
}else{
IFValue=0; /* There is no need of frequency amendment */
}
}else{
/* Gap confirmation of a plus direction */
if(FreqValue >= FREQ_VALID_RANGE){
IFValue-=FreqValue; /* Frequency amendment */
IFValue=(IFValue / 125) * 125;
}else{
IFValue=0; /* There is no need of frequency amendment */
}
}
if(IFValue != 0){
TunerData[0] = 0x1F; /* div high */
TunerData[1] = 0x40; /* div low */
TunerData[2] = 0x84; /* fixed val */
TunerData[3] = 0x86; /* LNB power */
if(IFValue < 1550000 ){ /* 1550MHz */
TunerData[3] |= 0x02;
}else{
TunerData[3] &= 0xFD;
}
IFWorkValue =IFValue;
IFWorkValue /= 125; /* divide by step size (125 Khz) */
TunerData[0] = (UI8) ((IFWorkValue >> 8) & 0xFF);
TunerData[1] = (UI8) (IFWorkValue & 0xFF);
TunerSendIIC(TUNER_I2C_ADDRESS,TunerData,(UI8)sizeof TunerData);
DRV_NIM_TUNER_InterFrequency = IFValue; /* Global */
return(FALSE); /* Frequency re-setting execution */
}else{
return(TRUE); /* NON Frequency re-setting */
}
}
/*****************************************************************
*
* Function Name
* QpskGetFreqDeviation
*
* Prototype
* static int QpskGetFreqDeviation(void)
*
* Inputs
* None
*
* Outputs
* None
*
* Return Codes
* Frequency Deviation Value
*
* Description
* This function a get frequency deviation value.
*
*****************************************************************/
static int QpskGetFreqDeviation(void)
{
double CalcValue;
int CalcData;
UI8 GetData[4];
if(TRUE==GetRegister(3,7,GetData,3)){ /* Group3 APR7-9 NCO (Read Length=3) */
CalcData = (int)GetData[0];
CalcData += ((int)GetData[1] << 8);
CalcData += ((int)GetData[2] << 16); /* read Phase Tracking Frequency Accumulator */
}else{
CalcData = 0; /* FAUSE */
}
if( CalcData & 0x00800000 ){
CalcData -= 0x01000000;
}
CalcValue = -1 * ((double) CalcData) * QpskFsamp / 16777.216; /* CalcValue is @ KHz *-1 6/19 */
return((int)CalcValue);
}
/*****************************************************************
*
* Function Name
* DRV_NIM_QPSK_SetRegister
*
* Prototype
* BOOL DRV_NIM_QPSK_SetRegister(UI8 RegNumber,UI8 SetValue)
*
* Inputs
* RegNumber : Register Number
* SetValue : Setting Value
*
* Outputs
* None
*
* Return Codes
* TRUE : OK
* FALSE : ERROR (IIC Send Error)
*
* Description
* Setting of Group4 register.
*
*****************************************************************/
BOOL DRV_NIM_QPSK_SetRegister(UI8 RegNumber,UI8 SetValue)
{
DRV_IIC_SET_INFO IICInfo;
UI8 SetData;
UI8 AprGroup;
AprGroup=0x00; /* Sub Address APR0 */
SetData =RegNumber; /* setting Register Number */
/* APR0 set */
IICInfo.ChannelNumber = DRV_IIC_CHANNEL1; /* NIM Device IIC ch1 */
IICInfo.SlaveAddr = QPSK_CHIP_ADDR;
IICInfo.SubAddr = AprGroup;
IICInfo.Data = &SetData;
IICInfo.Length = 0x01;
IICInfo.NumSubAddressBytes = DRV_IIC_ONE_BYTE_ADDRESSING;
if((DRV_IIC_Write((DRV_IIC_SET_INFO *)&IICInfo))!=DRV_IIC_OK){
return(FALSE);
}
/* APR4 set */
AprGroup=0x04; /* Sub Address APR4 */
SetData =SetValue; /* setting Reg Value*/
IICInfo.SlaveAddr = QPSK_CHIP_ADDR;
IICInfo.SubAddr = AprGroup;
IICInfo.Data = &SetData;
IICInfo.Length = 0x01;
IICInfo.NumSubAddressBytes = DRV_IIC_ONE_BYTE_ADDRESSING;
if((DRV_IIC_Write((DRV_IIC_SET_INFO *)&IICInfo))!=DRV_IIC_OK){
return(FALSE);
}
return(TRUE);
}
/*****************************************************************
*
* Function Name
* GetRegister
*
* Prototype
* static UI8 GetRegister(UI8 RegGroup,UI8 RegNumber,UI8 *GetValue,UI8 GetLength)
*
* Inputs
* RegGroup : Register Group Number
* RegNumber : Register Number
* GetLength : Read Length
*
* Outputs
* GetData : Register Value set pointer
*
* Return Codes
* TRUE : OK
* FALSE : ERROR (IIC Send Error)
*
* Description
* Get L64724 register.
*
*****************************************************************/
static BOOL GetRegister(UI8 RegGroup,UI8 RegNumber,UI8 *GetData,UI8 GetLength)
{
DRV_IIC_SET_INFO IICInfo;
UI8 SetData;
UI8 AprGroup;
AprGroup=0x00; /* Sub Address APR0 */
SetData =RegNumber; /* setting Register Number */
/* APR0 set */
IICInfo.ChannelNumber = DRV_IIC_CHANNEL1; /* NIM Device IIC ch1 */
IICInfo.SlaveAddr = QPSK_CHIP_ADDR;
IICInfo.SubAddr = AprGroup;
IICInfo.Data = &SetData;
IICInfo.Length = 0x01;
IICInfo.NumSubAddressBytes = DRV_IIC_ONE_BYTE_ADDRESSING;
if((DRV_IIC_Write((DRV_IIC_SET_INFO *)&IICInfo))!=DRV_IIC_OK){
return(FALSE);
}
/* APR4 Get RegNumber Value */
AprGroup=RegGroup; /* Sub Address APRn */
IICInfo.SlaveAddr = QPSK_CHIP_ADDR;
IICInfo.SubAddr = AprGroup;
IICInfo.Data = GetData;
IICInfo.Length = (UI32)GetLength;
IICInfo.NumSubAddressBytes = DRV_IIC_ONE_BYTE_ADDRESSING;
if((DRV_IIC_Read((DRV_IIC_SET_INFO *)&IICInfo))!=DRV_IIC_OK){
return(FALSE);
}
return(TRUE);
}
/*****************************************************************
*
* Function Name
* CalcApr19
*
* Prototype
* static int CalcApr19(void)
*
* Inputs
* None
*
* Outputs
* None
*
* Return Codes
* calculation result
*
* Description
* Calculate of register number 19.
*
*****************************************************************/
static int CalcApr19(void)
{
int df_h,df_m,df_l;
#if 0
df_h = QpskDFNumber ;
#endif
if ( QpskDFNumber == 0) df_h = 4;
if ( QpskDFNumber == 1) df_h = 0;
if ( QpskDFNumber == 2) df_h = 1;
if ( QpskDFNumber == 3) df_h = 2;
if ( QpskDFNumber == 4) df_h = 3;
if ( QpskDFGain == 1) df_m = 0;
if ( QpskDFGain == 2) df_m = 1;
if ( QpskDFGain == 4) df_m = 2;
if ( QpskDFGain == 8) df_m = 3;
if ( QpskDFRatio == 1) df_l = 4;
if ( QpskDFRatio == 2) df_l = 0;
if ( QpskDFRatio == 4) df_l = 1;
if ( QpskDFRatio == 8) df_l = 2;
if ( QpskDFRatio == 16) df_l = 3;
return ( (df_h * 0x20) + (df_m * 0x8) + df_l) ;
}
/*****************************************************************
*
* Function Name
* CalcValue28
*
* Prototype
* static int CalcValue28 (int BaudRate, int SampleRate)
*
* Inputs
* BaudRate : Baud Rate @KHz
* SampleRate : Sampling Rate @MHz
*
* Outputs
* None
*
* Return Codes
* calculation result
*
* Description
* Calculate of register number 28.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -