hamaro_cx24128.c
来自「QPSK Tuner details, for conexant chipset」· C语言 代码 · 共 1,877 行 · 第 1/5 页
C
1,877 行
/*******************************************************************************************************
* HAMARO_TUNER_CX24128_GetVcoStatus()
* reads tuner register to get the Vco edge detection status
*******************************************************************************************************/
BOOL
HAMARO_TUNER_CX24128_GetVcoStatus(HAMARO_NIM *p_nim, /* pointer to nim */
HAMARO_VCOSTATUS *p_vcostatus) /* pointer to the returned vco status. */
{
unsigned char reg_value;
HAMARO_VCOMODE VcoMode;
HAMARO_TUNER_CX24128_VALIDATE(p_nim);
VcoMode = p_nim->tuner.cx24128.viperparms.VcoMode;
switch(VcoMode)
{
case HAMARO_VCOMODE_AUTO:
case HAMARO_VCOMODE_TEST:
{
/* read 0x17[0] */
if(HAMARO_TunerRegisterRead(p_nim, (unsigned short)(0x17), (unsigned long*)®_value, HAMARO_IO_UNKNOWN) != True)
return(False);
reg_value &= 0x01;
if (reg_value == 0x01UL)
{
*p_vcostatus = HAMARO_VCO_AUTO_FAIL;
}
else
{
*p_vcostatus = HAMARO_VCO_AUTO_DONE;
}
break;
}
default:
{
return(False);
break;
}
}
p_nim->tuner.cx24128.viperparms.VCOstatus = *p_vcostatus;
return(True);
}/* HAMARO_TUNER_CX24128_GetVcoStatus() */
/*******************************************************************************************************
* HAMARO_TUNER_CX24128_GetVcoStatus()
* reads tuner register to get the selected ICP level
*******************************************************************************************************/
BOOL
HAMARO_TUNER_CX24128_GetAnalogICPLevel(HAMARO_NIM *p_nim, HAMARO_ICPSELECT *p_icplevel)
{
unsigned char reg_value;
HAMARO_TUNER_CX24128_VALIDATE(p_nim);
/* get the selected level from the tuner */
/* read 0x12[1:0] */
if(HAMARO_TunerRegisterRead(p_nim, (unsigned short)(0x12), (unsigned long*)®_value, HAMARO_IO_UNKNOWN) != True)
return(False);
reg_value &= 0x03;
if (reg_value == 0)
{
*p_icplevel = HAMARO_ICPSELECT_LEVEL1;
}
else
{
*p_icplevel = (HAMARO_ICPSELECT)reg_value;
}
p_nim->tuner.cx24128.viperparms.ICPselect = *p_icplevel;
return(True);
}
/*******************************************************************************************************
* HAMARO_TUNER_CX24128_GetPLLFrequency()
* returns current frequency. programmed into the tuner pll register
*******************************************************************************************************/
#if 0
BOOL HAMARO_TUNER_CX24128_GetPLLFrequency(HAMARO_NIM *p_nim, /* pointer to nim */
unsigned long *p_pllfreq) /* pointer to unsigned long where pll frequency.*/
/* in Hz. will be returned */
{
unsigned short nvalue; /* Returned N value */
/*unsigned long*/int fvalue;
signed long fvalue_signed;
unsigned long Nfrac;
HAMARO_RDIVVAL R;
HAMARO_VCODIV vcodiv;
HAMARO_BCDNO bcd;
static sem_id_t semid= NULL;
BOOL retValue = False;
if (semid == NULL)
{
semid = sem_create(1, "GetPLLFreSem");
USPPrint(3, "GetPLLFreSem");
}
if (semid != NULL)
{
sem_get(semid, KAL_WAIT_FOREVER);
}
/* test for valid nim */
HAMARO_TUNER_CX24128_VALIDATE(p_nim);
if (p_pllfreq == 0)
{
HAMARO_DRIVER_SET_ERROR(p_nim, HAMARO_BAD_PARM);
goto extilabel;//return(False);
}
if (HAMARO_TUNER_CX24128_calc_pllNF(p_nim, &nvalue, &fvalue) == False )
{
goto extilabel;//return (False);
}
fvalue_signed = (signed long)(fvalue);
R = p_nim->tuner.cx24128.R;
vcodiv = p_nim->tuner.cx24128.vcodiv;
/* catch any div by zero errors */
if ((R != 0UL) && (vcodiv != 0UL))
{
/*
The frequency can be calculated from the crystal frequency and divider settings as follows:
FLO = [2 * Nfrac * (Fxtal/R)]/D
,where R = reference divider setting (either 1 or 2)
D = LO divider setting (either 2 or 4)
Fxtal = actual crystal frequency
Nfrac = total fractional divide ratio and can be calculated from
Nfrac = (Dividend/262144) + Nreg + 32
where, Dividend = DSM setting 18-bit signed value (between +/-131072)
Nreg = 9-bit divider setting
*/
/* multiplication factor of 10000 is used to improve precision */
Nfrac = ( (fvalue_signed * 10000L) / HAMARO_CX24128_DIVIDER) + (nvalue * 10000UL) + (32UL * 10000UL);
HAMARO_BCD_set (&bcd, (p_nim->tuner_crystal_freq / R));
HAMARO_BCD_mult(&bcd, Nfrac);
HAMARO_BCD_mult(&bcd, 2);
HAMARO_BCD_div (&bcd, 10000);
HAMARO_BCD_div (&bcd, vcodiv);
if ((p_nim->tuner_crystal_freq) / HAMARO_MM >= 20)
{
HAMARO_BCD_mult(&bcd, 2);
}
*p_pllfreq = HAMARO_BCD_out(&bcd);
retValue = True;
}
else
{
HAMARO_DRIVER_SET_ERROR(p_nim,HAMARO_BAD_DIV);
retValue = False;
}
extilabel:
if (semid != NULL)
{
sem_put(semid);
}
return (retValue);
}/* HAMARO_TUNER_CX24128_GetPLLFrequency() */
#else
BOOL
HAMARO_TUNER_CX24128_GetPLLFrequency(HAMARO_NIM *p_nim, /* pointer to nim */
unsigned long *p_pllfreq) /* pointer to unsigned long where pll frequency.*/
/* in Hz. will be returned */
{
unsigned short nvalue; /* Returned N value */
/*unsigned long*/int fvalue;
signed long fvalue_signed;
unsigned long Nfrac;
HAMARO_RDIVVAL R;
HAMARO_VCODIV vcodiv;
HAMARO_BCDNO bcd;
/* test for valid nim */
HAMARO_TUNER_CX24128_VALIDATE(p_nim);
if (p_pllfreq == 0)
{
HAMARO_DRIVER_SET_ERROR(p_nim, HAMARO_BAD_PARM);
return(False);
}
if (HAMARO_TUNER_CX24128_calc_pllNF(p_nim, &nvalue, &fvalue) == False )
{
return (False);
}
fvalue_signed = (signed long)(fvalue);
R = p_nim->tuner.cx24128.R;
vcodiv = p_nim->tuner.cx24128.vcodiv;
/* catch any div by zero errors */
if ((R != 0UL) && (vcodiv != 0UL))
{
/*
The frequency can be calculated from the crystal frequency and divider settings as follows:
FLO = [2 * Nfrac * (Fxtal/R)]/D
,where R = reference divider setting (either 1 or 2)
D = LO divider setting (either 2 or 4)
Fxtal = actual crystal frequency
Nfrac = total fractional divide ratio and can be calculated from
Nfrac = (Dividend/262144) + Nreg + 32
where, Dividend = DSM setting 18-bit signed value (between +/-131072)
Nreg = 9-bit divider setting
*/
/* multiplication factor of 10000 is used to improve precision */
Nfrac = ( (fvalue_signed * 10000L) / HAMARO_CX24128_DIVIDER) + (nvalue * 10000UL) + (32UL * 10000UL);
HAMARO_BCD_set (&bcd, (p_nim->tuner_crystal_freq / R));
HAMARO_BCD_mult(&bcd, Nfrac);
HAMARO_BCD_mult(&bcd, 2);
HAMARO_BCD_div (&bcd, 10000);
HAMARO_BCD_div (&bcd, vcodiv);
if ((p_nim->tuner_crystal_freq) / HAMARO_MM >= 20)
{
HAMARO_BCD_mult(&bcd, 2);
}
*p_pllfreq = HAMARO_BCD_out(&bcd);
}
else
{
HAMARO_DRIVER_SET_ERROR(p_nim,HAMARO_BAD_DIV);
return(False);
}
return(True);
}/* HAMARO_TUNER_CX24128_GetPLLFrequency() */
#endif
/*******************************************************************************************************
* HAMARO_TUNER_CX24128_pll_status
* reads current tuner pll lock status
*******************************************************************************************************/
BOOL
HAMARO_TUNER_CX24128_pll_status(HAMARO_NIM *p_nim, /* nim pointer */
BOOL *p_locked) /* BOOL pointer, where tuner pll lock status is returned */
{
unsigned char reg_value = 0;
if(HAMARO_CX24128_refresh_tuner_pll_lock == True)
{
/* read the tuner register to get tuner pll lock status */
/* read 0x10[1] */
if(HAMARO_TunerRegisterRead(p_nim, (unsigned short)(0x10), (unsigned long*)®_value, HAMARO_IO_UNKNOWN) != True)
{
return(False);
}
reg_value &= 0x02;
if (reg_value == 0x00)
{
*p_locked = False;
HAMARO_CX24128_tuner_pll_lock = False;
}
else
{
*p_locked = True;
HAMARO_CX24128_tuner_pll_lock = True;
}
HAMARO_CX24128_refresh_tuner_pll_lock = False;
}
else
{
*p_locked = HAMARO_CX24128_tuner_pll_lock;
}
return(True);
} /* HAMARO_TUNER_CX24128_pll_status() */
/*******************************************************************************************************
* HAMARO_TUNER_CX24128_calc_pllNF()
* function to calc pll settings (n,f) using bcd functions.
* input is the specified pll frequency, output is N, F values to be set
* to tuner and nim.
*******************************************************************************************************/
BOOL
HAMARO_TUNER_CX24128_calc_pllNF(HAMARO_NIM *p_nim, /* nim pointer */
unsigned short *nvalue, /* Returned N value. */
int *fvalue) /* Returned F value. */
{
long N;
long F;
HAMARO_RDIVVAL R;
HAMARO_VCODIV vcodiv;
HAMARO_BCDNO bcd;
unsigned char factor;
unsigned char reg_value;
/* set frequency to a default setting, if not presently set, test xtal for zero before divide. */
if (p_nim->pll_frequency == 0UL) p_nim->pll_frequency = HAMARO_NIM_DEFAULT_FREQ;
if (p_nim->tuner_crystal_freq == 0UL) p_nim->tuner_crystal_freq = HAMARO_NIM_DEFAULT_XTAL;
if ((p_nim->tuner_crystal_freq) /HAMARO_MM < 20)
{
factor = 1;
}
else
{
factor = 2;
}
/* Set lo divider to tuner and nim. */
if (((p_nim->pll_frequency) / HAMARO_MM) >= HAMARO_CX24128_LO_DIV_BREAKPOINT)
{
vcodiv = HAMARO_VCODIV2;
if (HAMARO_TUNER_CX24128_SetVcoDivider(p_nim,vcodiv) != True) return(False);
}
else
{
vcodiv = HAMARO_VCODIV4;
if (HAMARO_TUNER_CX24128_SetVcoDivider(p_nim,vcodiv) != True)
return(False);
}
/* Set reference divider to nim. */
HAMARO_TUNER_CX24128_SetReferenceDivider(p_nim,HAMARO_RDIV_1);
R = p_nim->tuner.cx24128.R;
/* calculate tuner PLL settings: */
/* Calculate N first. No need to use BCD functions. */
N = (p_nim->pll_frequency / 100UL * vcodiv) * R;
N /= ((p_nim->tuner_crystal_freq /HAMARO_M * factor) * 2UL);
N += 5UL; /* For round up. */
N /= 10UL;
N -= 32UL;
/* N has to be >= than 8. */
if (N < 8)
{
/* Set reference divider to nim. */
HAMARO_TUNER_CX24128_SetReferenceDivider(p_nim,HAMARO_RDIV_2);
R = p_nim->tuner.cx24128.R;
/* Calculate N again. No need to use BCD functions. */
N = (p_nim->pll_frequency * vcodiv / 100UL) * R;
N /= ((p_nim->tuner_crystal_freq * factor / HAMARO_M) * 2UL);
N += 5UL; /* For round up. */
N /= 10UL;
N -= 32UL;
if (N < 8)
{
return(False);
}
}
/* Now calculate F. */
HAMARO_BCD_set(&bcd,p_nim->pll_frequency);
HAMARO_BCD_mult(&bcd,((unsigned long)R * (unsigned long)vcodiv * HAMARO_CX24128_DIVIDER));
HAMARO_BCD_div(&bcd,(p_nim->tuner_crystal_freq * factor * 2UL));
F = HAMARO_BCD_out(&bcd);
F -= (N + 32) * HAMARO_CX24128_DIVIDER;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?