📄 cx24108_tuner.c
字号:
} /* _TUNER_CX24108_vcoband_manual() */
/*******************************************************************************************************/
/* _TUNER_CX24108_first_edgelock() */
/*******************************************************************************************************/
BOOL _TUNER_CX24108_first_edgelock( /* Function to find the first-lock position of vco edges detect */
NIM *nim, /* pointer to nim */
ULONG *mid_pt, /* point at which initial edge detection will start */
BOOL *locked, /* returns True if locked, (if False, error: failure to find initial edge) */
VCOSET vcoband) /* vco band number being scanned */
{
int i;
if (__TUNER_CX24108_first_edgeone(nim,mid_pt,locked,vcoband) == True) return(True);
/* find the first edge manually, return True when found */
for (i = 1 ; i < CX24108_MAX_FIRSTEDGE+1 ; i++)
{
*mid_pt += (i * (CX24108_NOMSTEP * CX24108_EDGESTEP));
if (__TUNER_CX24108_first_edgeone(nim,mid_pt,locked,vcoband) == True) return(True);
*mid_pt -= (i * (CX24108_NOMSTEP * CX24108_EDGESTEP));
*mid_pt -= (i * (CX24108_NOMSTEP * CX24108_EDGESTEP));
if (__TUNER_CX24108_first_edgeone(nim,mid_pt,locked,vcoband) == True) return(True);
*mid_pt += (i * (CX24108_NOMSTEP * CX24108_EDGESTEP));
}
/* unable to find a reasonable vco edge */
DRIVER_SetError(nim,API_TUNEREDGE);
return(False);
} /* _TUNER_CX24108_first_edgelock() */
/*******************************************************************************************************/
/* __TUNER_CX24108_first_edgeone() */
/*******************************************************************************************************/
BOOL __TUNER_CX24108_first_edgeone( /* Function to find the first-lock position of vco edges detect */
NIM *nim, /* pointer to nim */
ULONG *mid_pt, /* point at which initial edge detection will start */
BOOL *locked, /* returns True if locked, (if False, error: failure to find initial edge) */
VCOSET vcoband) /* vco band number being scanned */
{
int vcoidx = (int)vcoband; /* vco idx (0..n) is passed to funct (vcoidx indicates VCOSET index into vco struct) */
ULONG bm; /* band manual return */
/* change freq, test lock */
if (_TUNER_CX24108_freq_manual(nim,*mid_pt) == False) return(False);
bm = _TUNER_CX24108_vcoband_manual(nim,vcoidx);
if (_TUNER_CX24108_pll_status(nim,locked) == False) return(False);
if (*locked == True)
{
/* successful tune, and pll lock */
return(True);
}
return(False);
} /* __TUNER_CX24108_first_edgeone() */
/*******************************************************************************************************/
/* _TUNER_CX24108_pll_status( */
/*******************************************************************************************************/
BOOL _TUNER_CX24108_pll_status( /* reads current tuner pll lock status */
NIM *nim, /* nim pointer */
BOOL *locked) /* BOOL pointer, where tuner pll lock status is returned */
{
ULONG ulRegVal;
/* Lock assertion from tuner takes a short time. */
OS_Wait(nim,1);
/* read the demod's tuner lock indicator pin */
if (RegisterRead(nim,CX24130_TUNPLLLOCK,&ulRegVal) == False) return(False);
if (ulRegVal == 0UL) *locked = False;
else *locked = True;
return(True);
} /* _TUNER_CX24108_pll_status() */
/*******************************************************************************************************/
/* _TUNER_CX24108_set_registers() */
/*******************************************************************************************************/
BOOL _TUNER_CX24108_set_registers( /* function to set N, A, R registers in tuner */
NIM *nim, /* pointer to nim */
int nvalue, /* N register */
int avalue, /* A register */
RDIVVAL rvalue) /* R register */
{
int na;
DWORD bandbin;
DWORD vcodivbin;
ULONG tunpll;
ULONG ulRegVal;
ULONG Fr;
VCOSET vcoset; /* vco number vai VCOSET enum: VCO1D2 (aka VCO #1) .. VCO8D4 (aka VCO #11) */
VCONO vcono; /* vco number: always one of: 1,2,3,4,5,6,7,8 */
VCODIV vcodiv;
/* convert the rvalue into value to be programmed to the tuner */
if (_TUNER_CX24108_set_refdivider(nim,rvalue) == False) return(False);
/* save last n,a,r settings */
nim->tuner.cx24108.N = nvalue;
nim->tuner.cx24108.A = avalue;
nim->tuner.cx24108.R = rvalue;
/* determine frequency */
ulRegVal = ((ULONG)nvalue<<5)|(ULONG)avalue;
na = (int)ulRegVal;
Fr = _TUNER_CX24108_calc_Fpll(nim,na);
/* (CR 7795) */
nim->frequency = Fr;
/* set the tuner band-select bit settings */
if (_TUNER_CX24108_band_info(nim,Fr,&bandbin,&vcodivbin,&vcoset,&vcodiv,&vcono,&tunpll) == False) return(False);
ulRegVal = ((ULONG)vcodivbin<<9);
ulRegVal |= (ULONG)bandbin;
if (_TUNER_CX24108_io(nim,CX24108_BAND_PROG,ulRegVal) == False) return(False);
/* continue building data to send to tuner (via demod) */
ulRegVal = ((ULONG)nim->tuner.cx24108.RefDivider<<17UL); /* R Divider */
ulRegVal |= ((ULONG)nim->tuner.cx24108.CPCPolarity<<16UL); /* charge pump polarity */
ulRegVal |= (((ULONG)nim->tuner.cx24108.CPCCurrent&0x03UL)<<CX24108_CPC_START);
ulRegVal |= (((ULONG)nvalue&0x1ffUL)<<5UL);
ulRegVal |= ((ULONG)avalue&0x1fUL);
/* send built "string" to the tuner */
if (_TUNER_CX24108_io(nim,CX24108_PLL_PROG,ulRegVal) == False) return(False);
return(True);
} /* _TUNER_CX24108_set_registers() */
/*******************************************************************************************************/
/* _TUNER_CX24108_set_refdivider() */
/*******************************************************************************************************/
BOOL _TUNER_CX24108_set_refdivider(/* function to set the ref divider value prog'd to the tuner */
NIM *nim, /* pointer to nim (nim->RefDivider is set within nim) */
RDIVVAL rvalue) /* ref divider value (10,20...) */
{
int i;
static UCHAR _rvalue[] = {0x03,0x02, 0x01, 0x00}; /* value programmed to tuner */
static RDIVVAL rvalue_match[] = {RDIV_10,RDIV_20,RDIV_40,RDIV_UNDEF};
/* find the correct rvalue setting for the tuner */
for (i = 0 ; rvalue_match[i] != RDIV_UNDEF ; i++)
{
if (rvalue_match[i] == rvalue)
{
nim->tuner.cx24108.RefDivider = _rvalue[i];
return(True);
}
}
/* unable to equate rvalue to tuner setting */
DRIVER_SetError(nim,API_BAD_CXDATA);
return(False);
} /* _TUNER_CX24108_set_refdivider() */
/*******************************************************************************************************/
/* __TUNER_CX24108_set_freq() */
/*******************************************************************************************************/
BOOL _TUNER_CX24108_set_freq(/* set tuner to a desired frequency */
NIM *nim, /* pointer to nim */
ULONG freq) /* frequency in khz to set tuner to */
{
DWORD bandbin;
DWORD vcodivbin;
ULONG ulRegVal;
ULONG nar_str; /* string of bits to be written to tuner */
ULONG tunpll;
BOOL rtn1;
BOOL rtn2;
BOOL rtn3;
VCOSET vcoset; /* vco number via VCOSET enum: VCO1D2 (aka VCO #1) .. VCO8D4 (aka VCO #11) */
/* default: set the frequency, rdiv, vcodiv */
nim->frequency = freq;
nim->tuner.cx24108.vcodiv = VCODIV2;
/* special op to set freq 1mhz high */
_TUNER_CX24108_io_special(nim);
/* set the tuner band-select bit settings, plus set add'l tuner settings */
rtn1 = _TUNER_CX24108_band_info(nim,nim->frequency,&bandbin,&vcodivbin,&vcoset,
&nim->tuner.cx24108.vcodiv,&nim->tuner.cx24108.vcono,&tunpll);
/* set VCO divider and band-select data */
ulRegVal = vcodivbin;
ulRegVal <<= 9;
ulRegVal |= bandbin;
rtn2 = _TUNER_CX24108_io(nim,CX24108_BAND_PROG,ulRegVal);
/* write the pll setting to the tuner */
nar_str = _TUNER_CX24108_calc_pll(nim);
ulRegVal = nar_str;
ulRegVal |= ((ULONG)nim->tuner.cx24108.RefDivider<<17); /* ref divider programming bits */
ulRegVal |= ((ULONG)nim->tuner.cx24108.CPCPolarity<<16); /* charge pump polarity */
ulRegVal |= (((ULONG)nim->tuner.cx24108.CPCCurrent&0x03UL)<<CX24108_CPC_START);
rtn3 = _TUNER_CX24108_io(nim,CX24108_PLL_PROG,ulRegVal);
if (rtn1 != True || rtn2 != True || rtn3 != True) return(False);
return(True);
} /* __TUNER_CX24108_set_freq() */
/*******************************************************************************************************/
/* _TUNER_CX24108_calc_pll() */
/*******************************************************************************************************/
ULONG _TUNER_CX24108_calc_pll(/* function to calc pll settings (n,a) using bcd functions */
NIM *nim) /* nim pointer */
{
ULONG NA;
NA = _TUNER_CX24108_calc_pllNA(nim);
/* save the last NAR settings */
nim->tuner.cx24108.N = (int)((NA&0x3fffUL)>>5UL);
nim->tuner.cx24108.A = (int)(NA&0x1fUL);
/* this calculated N, A value is what is physically sent to the tuner */
/* the tuner has a feature where when A is zero, it tunes significantly above */
/* the calculated PLL freq. DO NOT USE THIS NA return value to perform calculations */
/* if the a portion of NA is zero, subtract 1 to n portion */
if ((NA&0x1fUL) == 0UL)
{
NA -= 32UL;
}
return(NA);
} /* _TUNER_CX24108_calc_pll() */
/*******************************************************************************************************/
/* _TUNER_CX24108_calc_pllNA() */
/*******************************************************************************************************/
ULONG _TUNER_CX24108_calc_pllNA( /* function to calc pll settings (n,a) using bcd functions */
NIM *nim) /* nim pointer */
{
ULONG NA;
/* set freq to a default setting, if not presently set, test xtal for zero before divide (CR 7452) */
if (nim->frequency == 0UL) nim->frequency = NIM_DEFAULT_FREQ;
if (nim->crystal_freq == 0UL) nim->crystal_freq = NIM_DEFAULT_XTAL;
NA = (nim->frequency / 100UL) * ((ULONG)nim->tuner.cx24108.R * (ULONG)nim->tuner.cx24108.vcodiv);
NA /= ((nim->crystal_freq / M) * 2UL);
NA += 5UL;
NA /= 10UL;
return(NA);
} /* _TUNER_CX24108_calc_pllNA() */
/*******************************************************************************************************/
/* _TUNER_CX24108_calculateNAR() */
/*******************************************************************************************************/
BOOL _TUNER_CX24108_CalculateNAR( /* function to calc pll settings (n,a) using bcd functions */
NIM *nim, /* nim pointer */
ULONG Fdesired, /* desired frequency */
RDIVVAL R, /* proposed reference divider */
DWORD *N, /* returned N value */
DWORD *A) /* returned A value */
{
ULONG NA;
BCDNO bcd;
/* calculate tuner PLL settings: */
BCD_set(&bcd,Fdesired);
BCD_mult(&bcd,((ULONG)R * (ULONG)nim->tuner.cx24108.vcodiv * M));
BCD_div(&bcd,(nim->crystal_freq * 2UL));
NA = BCD_out(&bcd);
NA += 500UL;
NA /= 1000UL;
*N = (int)((NA&0x3fffUL)>>5UL);
*A = (int)(NA&0x1fUL);
return(True);
} /* _TUNER_CX24108_CalculateNAR() */
/*******************************************************************************************************/
/* _TUNER_CX24108_SetGainSettings() */
/*******************************************************************************************************/
BOOL _TUNER_CX24108_SetGainSettings( /* function to set the VCA, VGA settings for CX24108 tuner */
NIM *nim, /* pointer to nim */
ULONG symbolrateksps) /* symbol rate determines the VCA, VGA settings */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -