📄 dcf_api.c
字号:
/* */
/* CONTEXT: Must be called from a non-interrupt context. */
/* */
/*****************************************************************************/
bool dcf_init_environment(DCF_NIM *pNim,
unsigned long u32DemodHandle,
DCF_BUS_WRITE BusWrite,
DCF_BUS_READ BusRead,
bool (*DCF_TUNER_Install)(DCF_NIM *pNim),
unsigned long u32DemodCrystalFreq,
DCF_TS_OUT *pTsOutFormat,
bool (*waitfunct)(int mscount))
{
unsigned char u8DcfChipID;
/* Sanity check: Test whether a valid NIM struct, a valid tuner,
and a valid wait funtion are installed. */
if(pNim == NULL || DCF_TUNER_Install == NULL || waitfunct == NULL)
return(False);
/* clear the entire nim struct */
memset(pNim, CNULL, sizeof(DCF_NIM));
/* stuff NIM the demodulator handle and demodulator crsytal. */
pNim->demod_type = DCF_8722;
/* set i2c slave address to access the demodulator internal registers. */
pNim->demod_handle = u32DemodHandle;
/* the demodulator external CLOCK in KHz - 28.8 MHz */
pNim->demod_xtal = u32DemodCrystalFreq;
/* register bus access function */
pNim->BusWrite = BusWrite;
pNim->BusRead = BusRead;
/* register wait function */
pNim->wait = waitfunct;
/* Install the tuner specified by the user */
if((*DCF_TUNER_Install)(pNim) == False)
{
return(False);
}
/* initialize the tuner specified by the caller in HAMARO_TUNER_install passed into this function */
if((*DCF_TUNER_Initialize)(pNim) == False)
{
return(False);
}
/* initialize demodulator */
/* step 1: s/w reset */
DCF_DRIVER_SW_Reset(pNim);
/* step 2: reset deinterleaver */
DCF_DRIVER_DI_SW_Reset(pNim);
/* step 3: get chip id */
DCF_DRIVER_Get_ChipID(pNim, &u8DcfChipID);
if(u8DcfChipID != DCF_DEMOD_CHIP_ID)
{
return(False);
}
pNim->demod_chipid = u8DcfChipID;
/* step3: reset all chip registers */
DCF_DRIVER_Init_Regs(pNim);
/* step 4: set output format */
dcf_set_outputformat(pNim, pTsOutFormat);
/* step 5: set default error count mode, bit error rate */
DCF_DRIVER_Init_Bert(pNim);
/* step 6: initalize error mode */
/* configure the working mode of the demodulator internal BERT. */
DCF_DRIVER_Set_BERT(pNim, (DCF_ERRSRC)(DCF_BERT_SRC), (DCF_ERRMODE)(DCF_BERT_MODE), (unsigned char)DCF_DEMOD_BERT_NBYTE);
/* step 7: initialize for C/N estimation */
dcf_init_CN_estimation(pNim);
pNim->cne_mean = 3000;
pNim->cne_offset = 0;
/* initialize the parameters of signal */
pNim->freq_ideal = 0;
pNim->symbol_rate_ideal = 0;
pNim->mod_type = DCF_QAM64; /* EQU_0 - 0x49 */
pNim->auto_spec_inv = 1; /* auto-detect spectrum inversion */
pNim->spec_inv = DCF_SPEC_INV_OFF; /* CTRL_3 - 0x00 */
pNim->annex = DCF_ANNEX_A; /* CTRL_3 - 0x00 */
pNim->exit_acquring = False;
pNim->isAutoQAMMode = False;
return(True);
}
/*****************************************************************************/
/* FUNCTION: dcf_change_channel */
/* */
/* PARAMETERS: pNim - pointer to DCF_NIM struct. */
/* pChanObj - pointer to the TUNING_SPEC structure containing */
/* parameters for the requested connection. */
/* */
/* DESCRIPTION: The function connects THOMSON Cable Front-End DCF8722 to */
/* the specified signal. */
/* */
/* RETURNS: True if successful, False if unsuccessful. */
/* */
/* CONTEXT: Must be called from a non-interrupt context. */
/* */
/*****************************************************************************/
bool dcf_change_channel(DCF_NIM *pNim, DCF_CHANOBJ *pChanObj)
{
bool bRetVal;
/* check the Annex mode, ITU-J83 Annex mode must be always ANNEX_A */
if(pChanObj->annex != DCF_ANNEX_A)
{
return (False);
}
/* set parameters */
pNim->mod_type = pChanObj->modulation;
pNim->freq_ideal = pChanObj->frequency;
pNim->symbol_rate_ideal = pChanObj->symbrate;
pNim->spec_inv = pChanObj->spectrum;
/* check the AUTO-QAM DETECTION mode */
if (DCF_MOD_QAMAUTO == pChanObj->modulation)
{
pNim->isAutoQAMMode = True;
}
else
{
pNim->isAutoQAMMode = False;
}
/* initialize scan parameters */
dcf_init_acq(pNim);
/* carrier and bit synchronization */
bRetVal = dcf_carrier_search(pNim);
/* carrier search return value */
/*debug_out(TL_ALWAYS, "dcf_carrier_search return %d\n", bRetVal);*/
return(bRetVal);
}
/*****************************************************************************/
/* FUNCTION: dcf_get_lockstatus */
/* */
/* PARAMETERS: pNim - pointer to DCF_NIM struct. */
/* pLocked - pointer to a boolean to indicate the lock status */
/* */
/* DESCRIPTION: The function get the current lock status. */
/* */
/* RETURNS: True if successful, False if unsuccessful. */
/* */
/* CONTEXT: Must be called from a non-interrupt context. */
/* */
/*****************************************************************************/
bool dcf_get_lockstatus (DCF_NIM *pNim, bool *pLocked)
{
unsigned char u8RegData;
bool bRetVal;
/* get the lock status of the STV0297 QAM demodulator */
/* read the internal register */
bRetVal = DCF_RegRead(pNim, gDemReg[ST0_RID_RS_DESC_15].addr, 1,
(unsigned char*)&u8RegData, DCF_DEMOD_I2C);
if(bRetVal == False)
return(False);
gDemReg[ST0_RID_RS_DESC_15].value = u8RegData;
/* get the lock status */
if (u8RegData & 0x80)
{
*pLocked = True;
}
else
{
*pLocked = False;
}
return(True);
}
/*****************************************************************************/
/* FUNCTION: dcf_init_CN_estimation */
/* */
/* PARAMETERS: pNim - pointer to DCF_NIM struct. */
/* */
/* DESCRIPTION: The function initializes a look-up table gn32ST0CN[][] and */
/* other global variables for C/N estimation. */
/* The look-up table gn32ST0CN[iQ][iD] gives the C/N estimated */
/* value for a given QAM size [iQ] and C/N ratio [iD]. */
/* */
/* RETURNS: True if successful, False if unsuccessful. */
/* */
/* CONTEXT: Must be called from a non-interrupt context. */
/* */
/*****************************************************************************/
bool dcf_init_CN_estimation(DCF_NIM *pNim)
{
signed long n32Q, n32D;
/* sanity check */
if(pNim == NULL)
return(False);
for(n32Q=0; n32Q<5; n32Q++)
{
for(n32D=0; n32D<40; n32D++)
{
gn32ST0CN[n32Q][n32D] = 100000;
}
}
/* QAM == 16 */
n32Q = (signed long)(DCF_QAM16);
for(n32D=0; n32D<15; n32D++)
{
gn32ST0CN[n32Q][n32D] = 10500 + ((15 - n32D) * 1000);
}
gn32ST0CN[n32Q][15] = 10500;
gn32ST0CN[n32Q][16] = 9000;
gn32ST0CN[n32Q][17] = 8120;
gn32ST0CN[n32Q][18] = 7300;
gn32ST0CN[n32Q][19] = 6530;
gn32ST0CN[n32Q][20] = 5870;
gn32ST0CN[n32Q][21] = 5310;
gn32ST0CN[n32Q][22] = 4790;
gn32ST0CN[n32Q][23] = 4320;
gn32ST0CN[n32Q][24] = 3920;
gn32ST0CN[n32Q][25] = 3590;
gn32ST0CN[n32Q][26] = 3270;
gn32ST0CN[n32Q][27] = 3000;
gn32ST0CN[n32Q][28] = 2760;
gn32ST0CN[n32Q][29] = 2560;
gn32ST0CN[n32Q][30] = 2420;
gn32ST0CN[n32Q][31] = 2260;
gn32ST0CN[n32Q][32] = 2150;
gn32ST0CN[n32Q][33] = 2060;
gn32ST0CN[n32Q][34] = 1980;
gn32ST0CN[n32Q][35] = 1910;
gn32ST0CN[n32Q][36] = 1850;
gn32ST0CN[n32Q][37] = 1810;
gn32ST0CN[n32Q][38] = 1750;
gn32ST0CN[n32Q][39] = 1740;
/* QAM == 32 */
n32Q = (signed long)(DCF_QAM32);
for(n32D=0; n32D<18; n32D++)
{
gn32ST0CN[n32Q][n32D] = 10500 + ((18 - n32D) * 1000);
}
gn32ST0CN[n32Q][18] = 10500;
gn32ST0CN[n32Q][19] = 9120;
gn32ST0CN[n32Q][20] = 8100;
gn32ST0CN[n32Q][21] = 7300;
gn32ST0CN[n32Q][22] = 6560;
gn32ST0CN[n32Q][23] = 5930;
gn32ST0CN[n32Q][24] = 5380;
gn32ST0CN[n32Q][25] = 4920;
gn32ST0CN[n32Q][26] = 4520;
gn32ST0CN[n32Q][27] = 4130;
gn32ST0CN[n32Q][28] = 3800;
gn32ST0CN[n32Q][29] = 3520;
gn32ST0CN[n32Q][30] = 3290;
gn32ST0CN[n32Q][31] = 3120;
gn32ST0CN[n32Q][32] = 2980;
gn32ST0CN[n32Q][33] = 2850;
gn32ST0CN[n32Q][34] = 2730;
gn32ST0CN[n32Q][35] = 2650;
gn32ST0CN[n32Q][36] = 2560;
gn32ST0CN[n32Q][37] = 2510;
gn32ST0CN[n32Q][38] = 2480;
gn32ST0CN[n32Q][39] = 2440;
/* QAM == 64 */
n32Q = (signed long)(DCF_QAM64);
for(n32D=0; n32D<21; n32D++)
{
gn32ST0CN[n32Q][n32D] = 10500 + ((21 - n32D) * 1000);
}
gn32ST0CN[n32Q][21] = 10500;
gn32ST0CN[n32Q][22] = 9300;
gn32ST0CN[n32Q][23] = 8400;
gn32ST0CN[n32Q][24] = 7600;
gn32ST0CN[n32Q][25] = 6850;
gn32ST0CN[n32Q][26] = 6250;
gn32ST0CN[n32Q][27] = 5750;
gn32ST0CN[n32Q][28] = 5250;
gn32ST0CN[n32Q][29] = 4850;
gn32ST0CN[n32Q][30] = 4450;
gn32ST0CN[n32Q][31] = 4200;
gn32ST0CN[n32Q][32] = 3900;
gn32ST0CN[n32Q][33] = 3700;
gn32ST0CN[n32Q][34] = 3550;
gn32ST0CN[n32Q][35] = 3400;
gn32ST0CN[n32Q][36] = 3300;
gn32ST0CN[n32Q][37] = 3200;
gn32ST0CN[n32Q][38] = 3130;
gn32ST0CN[n32Q][39] = 3060;
/* QAM == 128 */
n32Q = (signed long)(DCF_QAM128);
for(n32D=0; n32D<24; n32D++)
{
gn32ST0CN[n32Q][n32D] = 10500 + ((24 - n32D) * 1000);
}
gn32ST0CN[n32Q][24] = 10500;
gn32ST0CN[n32Q][25] = 9660;
gn32ST0CN[n32Q][26] = 8780;
gn32ST0CN[n32Q][27] = 7970;
gn32ST0CN[n32Q][28] = 7310;
gn32ST0CN[n32Q][29] = 6750;
gn32ST0CN[n32Q][30] = 6220;
gn32ST0CN[n32Q][31] = 5810;
gn32ST0CN[n32Q][32] = 5430;
gn32ST0CN[n32Q][33] = 5090;
gn32ST0CN[n32Q][34] = 4880;
gn32ST0CN[n32Q][35] = 4700;
gn32ST0CN[n32Q][36] = 4500;
gn32ST0CN[n32Q][37] = 4340;
gn32ST0CN[n32Q][38] = 4270;
gn32ST0CN[n32Q][39] = 4150;
/* QAM == 256 */
n32Q = (signed long)(DCF_QAM256);
for(n32D=0; n32D<28; n32D++)
{
gn32ST0CN[n32Q][n32D] = 10500 + ((28 - n32D) * 1000);
}
gn32ST0CN[n32Q][28] = 10500;
gn32ST0CN[n32Q][29] = 9600;
gn32ST0CN[n32Q][30] = 9000;
gn32ST0CN[n32Q][31] = 8400;
gn32ST0CN[n32Q][32] = 7800;
gn32ST0CN[n32Q][33] = 7400;
gn32ST0CN[n32Q][34] = 7100;
gn32ST0CN[n32Q][35] = 6700;
gn32ST0CN[n32Q][36] = 6550;
gn32ST0CN[n32Q][37] = 6370;
gn32ST0CN[n32Q][38] = 6200;
gn32ST0CN[n32Q][39] = 6150;
return(True);
}
/*****************************************************************************/
/* FUNCTION: dcf_get_CN */
/* */
/* PARAMETERS: pNim - pointer to DCF_NIM struct. */
/* */
/* DESCRIPTION: The function gets the current C/N estimator. */
/* */
/* RETURNS: True if successful, False if unsuccessful. */
/* */
/* CONTEXT: Must be called from a non-interrupt context. */
/* */
/*****************************************************************************/
bool dcf_get_CN(DCF_NIM *pNim)
{
unsigned short u16Temp;
int i;
unsigned char u8ModType;
signed char n8D;
signed long n32CurrentMean, n32ComputedMean, n32OldMean;
/* Get QAM size */
dcf_get_qam_size(pNim);
u8ModType = pNim->mod_type;
/* unsupported QAM size */
if(u8ModType == 0xFF)
return(False);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -