📄 drv_nim_qpsk.c
字号:
/****************************************************************
*
* FILENAME
* DRV_NIM.c
*
* PURPOSE
* EMMA2L Reference Model NIM Driver
*
* AUTHOR
* Kenji.Matsuura
*
* DATE
* 09/04/2002
*
* HISTORY
*
*
*****************************************************************/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "COM.h"
#include "DRV_Internal.h"
#include "mmac/rtos.h"
#include "DRV_NIM.h"
#include "DRV_IIC.h"
#include "DRV_NIM_QPSK_Internal.h"
#include "DRV_NIM_TUNER_Internal.h"
#include "mmac/iic.h" /* m-kenji IIC */
/****************************************************************
* External Valiables
****************************************************************/
extern BOOL DRV_NIM_Initialized; /* NIM Driver Initialized Flag */
extern I32 DRV_NIM_TUNER_InterFrequency; /* Intermeiate Frequency */
extern UI8 DRV_NIM_FreqSweepControl; /* Frequency Sweep Stop Enable */
extern UI8 DRV_NIM_FreqSweepStatus; /* Frequency Sweep Status Run */
extern UI8 DRV_NIM_FreqAmendmentControl; /* Frequency Amendment Control */
extern UI8 DRV_NIM_FreqAmendmentStatus; /* Frequency Amendment Status Run */
/*****************************************************************
* Global Variables
*****************************************************************/
DRV_NIM_QPSK_STATUS DRV_NIM_QPSK_StatusInfo;
/****************************************************************
* Static Functions
****************************************************************/
static BOOL DRV_NIM_QPSK_SetG4Reg(void);
static BOOL QpskFreqValidRangeCheck(void);
static int QpskGetFreqDeviation(void);
static BOOL GetRegister(UI8 RegGroup,UI8 RegNumber,UI8 *GetData,UI8 GetLength);
static int CalcApr19(void);
static int CalcValue28(int BaudRate, int SampleRate);
static int CalcValue42(int BaudRate, int SampleRate,double Ratio);
static BOOL QpskClkSweepSwitch(UI8 Switch);
static BOOL QpskCarSweepSwitch(UI8 Switch);
static BOOL QPSK_FEC_Reset(void);
/****************************************************************
* Static Valiables
****************************************************************/
static int QpskSymbolRate; /* current symbol rate */
static int QpskDFNumber; /* Number */
static int QpskDFRatio; /* Ratio */
static int QpskDFGain; /* Gain */
static int QpskCarSweepLim; /* Carrier sweep limit */
static int QpskFsamp; /* SymbolRate sampling freqency */
static DRV_NIM_QPSK_VITERBI_RATE QpskViterbiRate; /* Vterbi Rate */
/* QPSK L64724 GRP4 Reg */
static UI8 Regs724[] = {
0x81, /* 00: 1, ,PLL_N[5:0] */
0x14, /* 01: , ,PLL_S[5:0] */
0x06, /* 02: IMQ,DSS,QB,PLL_T[4:0] */
0x18, /* 03: VitCodeRate[2:0],TEI,SYNC2,SYNC1,PLL_M[1:0] */
0x80, /* 04: VMDC1[7:0] */
0xA0, /* 05: VMDC2L[7:0] */
0x25, /* 06: VMDC2M[15:8] */
0x26, /* 07: VMDC2H[23:16] */
0x2E, /* 08: VitMax BER Count @Rate 1/2 */
0x19, /* 09: VitMax BER Count @Rate 2/3 */
0x0F, /* 10: VitMax BER Count @Rate 3/4 */
0x0A, /* 11: VitMax BER Count @Rate 5/6 */
0x07, /* 12: VitMax BER Count @Rate 6/7 */
0x07, /* 13: VitMax BER Count @Rate 7/8 */
0x47, /* 14: Sync Word[7:0] */
0x00, /* 15: BER,AutoRate,,,IMQ_EN,DI_Bypass,L[1:0] */
0x23, /* 16: ,,SSS[1:0],SSA[1:0]SST[1:0] */
0x20, /* 17: ,,OF,OutputSelector[4:0] */
0x00, /* 18: PLL_RESET */
0x84, /* 19: DF_Sel[2:0],DF_Gain[1:0],DF_Ratio[2:0] */
0x01, /* 20: ,,,PD,,,,MF_20_35 */
0x20, /* 21: PCLK_INV,PLL_BP,LCLK_OFF,CLK_DIV[4:0] */
0xAA, /* 22: CLK_DIV2[7:0] */
0xC2, /* 23: DC_Offset_On_Off[1:0],,CLK_DIV2[12:8] */
0x54, /* 24: PWR_REF[7:0] */
0x00, /* 25: ,,,,,INT_DC,PWR_BW[1:0] */
0xBB, /* 26: SCALE[7:0] */
0x64, /* 27: SNR_THSS[7:0] */
0xAA, /* 28: CAR_LAMBDA_SEL[3:0],CAR_MU_SEL[3:0] */
0x10, /* 29: CAR_LC_THSL[7:0] SAMSNG is 0x10 */
0x00, /* 30: ,,,,,,,, */
0xA0, /* 31: RS Bit/Byte,Errout_Inv,SPI_ON_ON,00000 */
0x8E, /* 32: CAR_SWR[7:0] */
0x2B, /* 33: CAR_SWR[15:8] */
0x9A, /* 34: CAR_USWL[7:0] */
0x19, /* 35: CAR_USWL[15:8] */
0x66, /* 36: CAR_LSWL[7:0] */
0xE6, /* 37: CAR_LSWL[15:8] */
0xB8, /* 38: CAR_LF_INIT[7:0] */
0x1E, /* 39: CAR_LF_INIT[15:8] */
0x05, /* 40: CAR_LF_INIT[23:16] */
0x65, /* 41: CAR_SWP_SWAP,CAR_ERROR_SWAP,CAR_AUTO_SWP,,,CAR_PD_SEL,CAR_OPEN,CAR_SW */
0xAA, /* 42: CLK_LAMBDA_SEL[3:0],CLK_MU_SEL[3:0] */
0x00, /* 43: CLK_SWR[7:0] */
0x44, /* 44: CLK_SWR[15:8] */
0x00, /* 45: CLK_USWL[7:0] */
0x00, /* 46: CLK_USWL[15:8] */
0x00, /* 47: CLK_LSWL[7:0] */
0x00, /* 48: CLK_LSWL[15:8] */
0x84, /* 49: CLK_BIAS[7:0] */
0x01, /* 50: CLK_BIAS[15:8] */
0x00, /* 51: CLK_BIAS[23:16] */
0x00, /* 52: CLK_BIAS[30:24] */
0x39, /* 53: CLK_SWP_SWAP,CLK_ERROR_SWAP,CLK_AUTO_SWP,,AGC_CLK_SEL,,CLK_OPEN,CLK_SW */
0x00, /* 54: SNR_EST,PWRP_TRI,ADC_PD,FP_LOCK_LEN,PWRP,,,CLK_ALPHA_SEL */
/* 0x08 ... SL5659 , 0x00 ....MI5769 AGC polarity setting */
0x0F, /* 55: ADC_BPS,OB_2C,XCTR[3:0],DEMOD_RST,FEC_RST */
0x00, /* 56: ,,,,,,, */
0x00, /* 57: ,,,,,,, */
0x14, /* 58: ,,,,,,, */
0x10, /* 59: TXSD[6:0], */
0x00, /* 60: STXD[7:0] */
0x00, /* 61: TXED[7:0] */
0x09, /* 62: Serial_B,Serial_C[1:0],SPI_M[3:0],Serial_A */
0x43, /* 63: FMODE,SPI_CLK_AND,SPI_Mode_A_B,,SPI_N[3:0] (BCLKOUT AND'ed DVALIDOUT) */
0x32, /* 64: SPI_Gain[7:0] */
0x00, /* 65: ,,,,,,SIP_Gain[9:8] */
0x66, /* 66: SPI_Bias[7:0] */
0x66, /* 67: SPI_Bias[15:8] */
0x06, /* 68: ,SPI_Bias[22:16] */
0x4B /* 69: CLK_LC_THS[7:0] */
};
static UI8 InitRegs724[] = {
0x81,0x14,0x06,0x18,0x80,0xA0,0x25,0x26,0x2E,0x19,0x0F,0x0A,
0x07,0x07,0x47,0x00,0x23,0x20,0x00,0x84,0x01,0x20,0xAA,0xC2,
0x54,0x00,0xBB,0x64,0xAA,0x10,0x00,0xA0,0x8E,0x2B,0x9A,0x19,
0x66,0xE6,0xB8,0x1E,0x05,0x65,0xAA,0x00,0x44,0x00,0x00,0x00,
0x00,0x84,0x01,0x00,0x00,0x39,0x00,0x0F,0x00,0x00,0x14,0x10,
0x00,0x00,0x09,0x43,0x32,0x00,0x66,0x66,0x06,0x4B};
static DF_TABLE DFTable[] = {
{4, 8, 8}, /* 0 ~ 3.75 Msps */
{3, 4, 4}, /* 3.75~ 7.5 Msps */
{2, 2, 2}, /* 7.5 ~ 15 Msps */
{1, 1, 1}, /* 15 ~ 30 Msps */
{0, 1, 1}, /* 30 ~ 44.5 Msps */
{0, 1, 1} /* 45Msps */
};
static PLL_TABLE PLLConst[] = {
{ 61, 1, 10, 3},
{ 6, 1, 1, 3},
{ 17, 1, 3, 3},
{ 16, 1, 3, 3},
{ 5, 1, 1, 3}, /* 75 */
{ 14, 1, 3, 2},
{ 13, 1, 3, 2},
{ 4, 1, 1, 1},
{ 11, 1, 3, 1},
{ 10, 1, 3, 0}, /* 50 */
{ 3, 1, 1, 0},
{ 8, 3, 1, 3},
{ 7, 3, 1, 2},
{ 2, 1, 1, 1},
{ 5, 3, 1, 0}, /* 25 */
{ 4, 3, 1, 0},
{ 1, 1, 1, 2},
{ 2, 3, 1, 2}
};
static int PLLConstantFs[17] = {
91, 90, 85, 80, 75,
70, 65, 60, 55, 50,
45, 40, 35, 30, 25,
20, 15
};
static double RsBound[7]={0,3750,7500,15000,30000,44500,45000};
static VITERBI_RATE_TBL StVCR[] ={
{ 1,2 }, /* VCR 0 = 1/2 */
{ 2,3 }, /* VCR 1 = 2/3 */
{ 3,4 }, /* VCR 2 = 3/4 */
{ 5,6 }, /* VCR 3 = 5/6 */
{ 6,7 }, /* VCR 4 = 6/7 */
{ 7,8 }, /* VCR 5 = 7/8 */
{ 3,4 }, /* VCR 6(Unused) = 3/4 */
{ 3,4 } /* VCR 7(Unused) = 3/4 */
};
#define XO_REF (double)15.0 // Crystal frequency (MHz)
/*****************************************************************
*
* Function Name
* DRV_NIM_QPSK_SetSymbolRate
*
* Prototype
* DRV_NIM_RESULT DRV_NIM_QPSK_SetSymbolRate(
* I32 Device,
* I32 SymbolRate,
* DRV_NIM_QPSK_VITERBI_RATE ViterbiRate)
*
*
* Inputs
* Device : NIM Device Number
* SymbolRate : Symbol Rate Value
* ViterbiRate : Viterbi Rate Value
*
* Outputs
* None
*
* Return Codes
* DRV_NIM_OK
* DRV_NIM_NOT_INITIALIZED
* DRV_NIM_INVALID_PARAMETER
* DRV_NIM_FAIL
*
* Description
* This function a setting of symbol rate.
*
*****************************************************************/
DRV_NIM_RESULT DRV_NIM_QPSK_SetSymbolRate(
I32 Device,I32 SymbolRate,DRV_NIM_QPSK_VITERBI_RATE ViterbiRate)
{
int i;
if( !DRV_NIM_Initialized ) { /* Not Initialized ? */
return( DRV_NIM_NOT_INITIALIZED ); /* Not Initialized */
}
SymbolRate /= 1000; /* 偲傝偁偊偢丄妱偭偲偔 by Soga */
#if DRV_NIM_CHECK_PARAMETER
if(!((0<=Device)&&(Device<DRV_NIM_NUMBER_OF_DEVICES))){ /* Invalid Device Number ? */
return( DRV_NIM_INVALID_PARAMETER ); /* Invalid Parameter */
}
if((SymbolRate < DRV_NIM_MINIMUM_SYMBOLRATE)||
(SymbolRate > DRV_NIM_MAXIMUM_SYMBOLRATE)){
return( DRV_NIM_INVALID_PARAMETER );
}
switch(ViterbiRate){
case DRV_NIM_QPSK_VITERBI_AUTO:
case DRV_NIM_QPSK_VITERBI_1_2:
case DRV_NIM_QPSK_VITERBI_2_3:
case DRV_NIM_QPSK_VITERBI_3_4:
case DRV_NIM_QPSK_VITERBI_5_6:
case DRV_NIM_QPSK_VITERBI_6_7:
case DRV_NIM_QPSK_VITERBI_7_8:
break;
default:
return( DRV_NIM_INVALID_PARAMETER );
}
#endif
if( MMAC_RTOS_AcquireSemaphore( DRV_NIM_Semaphore
, MMAC_RTOS_SUSPEND ) != MMAC_RTOS_OK ) { /* Take Semaphore for Callback Table NG ? */
return( DRV_NIM_FAIL ); /* Fail */
}
QpskSymbolRate = SymbolRate;
QpskViterbiRate= ViterbiRate;
/* select of carrier sweep limit */
if( QpskSymbolRate >= 15000 ){
QpskCarSweepLim = CARRIER_SWEEP_LIMIT_HIGH;
}else{
if( (7500 <= QpskSymbolRate) && ( 15000 > QpskSymbolRate)){
QpskCarSweepLim = CARRIER_SWEEP_LIMIT_MID;
}else{
if( (3750 <= QpskSymbolRate) && ( 7500 > QpskSymbolRate)){
QpskCarSweepLim = CARRIER_SWEEP_LIMIT_MID_1;
}else{
QpskCarSweepLim = CARRIER_SWEEP_LIMIT_LOW;
}
}
}
/* Calcurate DF param and Decide SampleRate frequency for ADC */
QpskDFNumber = 3 ; /* DF Number */
QpskDFRatio = 4 ; /* DF Ratio */
QpskDFGain = 4 ; /* DF Gain */
for ( i=0; i<6 ; i++){
if ( ( QpskSymbolRate > RsBound[i]) && ( QpskSymbolRate <= RsBound[i+1])){
QpskDFNumber = DFTable[i].DFNumber; /* DF Number */
QpskDFRatio = DFTable[i].DFRatio; /* DF Ratio */
QpskDFGain = DFTable[i].DFGain; /* DF Gain */
break;
}
}
/* Setting of symbol rate freqency sampling */
QpskFsamp = (int)(((4 * QpskDFRatio * QpskSymbolRate / (1010)) /5 ) * 5.0);
if (QpskFsamp < 10 ){ /* Min. 10MHz */
QpskFsamp = 10;
}
if (QpskFsamp > 90 ){ /* Max. 90MHz */
QpskFsamp = 90;
}
if ( QpskSymbolRate == 45000 ) { /* This is Max SymbolRate */
QpskDFNumber = 0;
QpskDFRatio = 1;
QpskDFGain = 1;
}
if(FALSE==DRV_NIM_QPSK_SetG4Reg()){ /* Register set */
MMAC_RTOS_ReleaseSemaphore( DRV_NIM_Semaphore );
return( DRV_NIM_FAIL ); /* Fail */
}
DRV_NIM_FreqSweepStatus=QPSK_SW_ON; /* Sweep Status ON (Run) */
if( MMAC_RTOS_ReleaseSemaphore( DRV_NIM_Semaphore ) != MMAC_RTOS_OK ) {
return( DRV_NIM_FAIL ); /* Fail */
}
return( DRV_NIM_OK );
}
/*****************************************************************
*
* Function Name
* DRV_NIM_QPSK_GetStatus
*
* Prototype
* DRV_NIM_RESULT DRV_NIM_QPSK_GetStatus(I32 Device,DRV_NIM_QPSK_STATUS *QpskStatus)
*
* Inputs
* Device : NIM Device Number
*
* Outputs
* QpskStatus : Qpsk status value pointer
* SignalLevel / QualityLevel / LockStatus
*
* Return Codes
* DRV_NIM_OK
* DRV_NIM_NOT_INITIALIZED
* DRV_NIM_INVALID_PARAMETER
* DRV_NIM_FAIL
*
* Description
* This function a get qpsk status.
*
*****************************************************************/
DRV_NIM_RESULT DRV_NIM_QPSK_GetStatus(I32 Device,DRV_NIM_QPSK_STATUS *QpskStatus)
#if 1
{
if( !DRV_NIM_Initialized ) { /* Not Initialized ? */
return( DRV_NIM_NOT_INITIALIZED ); /* Not Initialized */
}
#if DRV_NIM_CHECK_PARAMETER
if(!((0<=Device)&&(Device<DRV_NIM_NUMBER_OF_DEVICES))){ /* Invalid Device Number ? */
return( DRV_NIM_INVALID_PARAMETER ); /* Invalid Parameter */
}
if(QpskStatus==NULL){
return( DRV_NIM_INVALID_PARAMETER );
}
#endif
QpskStatus->SignalLevel = DRV_NIM_QPSK_StatusInfo.SignalLevel;
QpskStatus->QualityLevel= DRV_NIM_QPSK_StatusInfo.QualityLevel;
QpskStatus->LockStatus = DRV_NIM_QPSK_StatusInfo.LockStatus;
return( DRV_NIM_OK );
}
#else
{ /* debag */
UI8 GetValue;
UI16 AGCLevel;
UI16 SNRLevel;
/* acquire a register than L64724 */
if(FALSE==GetRegister(3,10,&GetValue,1)) /* Group3 APR10 (AGC Value) */
return( DRV_NIM_FAIL );
AGCLevel =(I16)(128-(GetValue/2));
QpskStatus->SignalLevel=(I8)AGCLevel;
if(FALSE==GetRegister(3,22,&GetValue,1)) /* Group3 APR22 (SNR[7:0] Value) */
return( DRV_NIM_FAIL );
SNRLevel = GetValue;
if(FALSE==GetRegister(3,23,&GetValue,1)) /* Group3 APR23 (SNR[11:8] Value) */
return( DRV_NIM_FAIL );
SNRLevel |= (GetValue << 8);
SNRLevel /= 32;
QpskStatus->QualityLevel=(I8)SNRLevel;
/* status check */
if(FALSE==GetRegister(3,11,&GetValue,1)) /* Group3 APR11 (Carrier and FEC Status) */
return( DRV_NIM_FAIL );
switch(GetValue & 0x17){
case 0x17: /* Status : VITERBI Lock */
QpskStatus->LockStatus=DRV_NIM_VITERBI_LOCK;
break;
case 0x10: /* Status : QPSK Lock */
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x16:
QpskStatus->LockStatus=DRV_NIM_QPSK_LOCK;
break;
default:
QpskStatus->LockStatus=DRV_NIM_UNLOCK;
break;
}
return( DRV_NIM_OK );
}
#endif
/*****************************************************************
*
* Function Name
* DRV_NIM_QPSK_GetSymbolRate
*
* Prototype
* DRV_NIM_RESULT DRV_NIM_QPSK_GetSymbolRate(
* I32 Device,I32 *SymbolRate,DRV_NIM_QPSK_VITERBI_RATE *ViterbiRate);
*
* Inputs
* Device : NIM Device Number
*
* Outputs
* SymbolRate : Symbol Rate Value pointer
* ViterbiRate : Viterbi Rate Value pointer
*
* Return Codes
* DRV_NIM_OK
* DRV_NIM_NOT_INITIALIZED
* DRV_NIM_INVALID_PARAMETER
* DRV_NIM_FAIL
*
* Description
* This function a get SymbolRate or ViterbiRate.
*
*****************************************************************/
DRV_NIM_RESULT DRV_NIM_QPSK_GetSymbolRate(
I32 Device,I32 *SymbolRate,DRV_NIM_QPSK_VITERBI_RATE *ViterbiRate)
{
if( !DRV_NIM_Initialized ) { /* Not Initialized ? */
return( DRV_NIM_NOT_INITIALIZED ); /* Not Initialized */
}
#if DRV_NIM_CHECK_PARAMETER
if(!((0<=Device)&&(Device<DRV_NIM_NUMBER_OF_DEVICES))){ /* Invalid Device Number ? */
return( DRV_NIM_INVALID_PARAMETER ); /* Invalid Parameter */
}
if(SymbolRate==NULL){
return( DRV_NIM_INVALID_PARAMETER );
}
if(ViterbiRate==NULL){
return( DRV_NIM_INVALID_PARAMETER );
}
#endif
*SymbolRate = QpskSymbolRate;
*ViterbiRate = QpskViterbiRate;
return( DRV_NIM_OK );
}
/*****************************************************************
*
* Function Name
* DRV_NIM_QPSK_GetSpectrum
*
* Prototype
* DRV_NIM_RESULT DRV_NIM_QPSK_GetSpectrum(I32 Device,I8 *Spectrum );
*
* Inputs
* Device : NIM Device Number
*
* Outputs
* Spectrum : Spectrum data pointer
*
* Return Codes
* DRV_NIM_OK
* DRV_NIM_NOT_INITIALIZED
* DRV_NIM_INVALID_PARAMETER
* DRV_NIM_FAIL
*
* Description
* This function a get Spectrum.
*
*****************************************************************/
DRV_NIM_RESULT DRV_NIM_QPSK_GetSpectrum(I32 Device,I8 *Spectrum )
{
UI8 GetValue;
if( !DRV_NIM_Initialized ) { /* Not Initialized ? */
return( DRV_NIM_NOT_INITIALIZED ); /* Not Initialized */
}
#if DRV_NIM_CHECK_PARAMETER
if(!((0<=Device)&&(Device<DRV_NIM_NUMBER_OF_DEVICES))){ /* Invalid Device Number ? */
return( DRV_NIM_INVALID_PARAMETER ); /* Invalid Parameter */
}
if(Spectrum==NULL){
return( DRV_NIM_INVALID_PARAMETER );
}
#endif
if( MMAC_RTOS_AcquireSemaphore( DRV_NIM_Semaphore
, MMAC_RTOS_SUSPEND ) != MMAC_RTOS_OK ) { /* Take Semaphore for Callback Table NG ? */
return( DRV_NIM_FAIL ); /* Fail */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -