📄 hamaro_cx24108.c
字号:
_HAMARO_TUNER_CX24108_initialize(nim);
/* save the current CPC setting to be restored after edge detection is done */
CPCCurrent = nim->tuner.cx24108.CPCCurrent;
/* step through each vco using index. stop after last vco (HAMARO_VCO8D4) is processed */
for (vcoidx = 0 ; vcoidx < (HAMARO_VCO8D2+1) ; vcoidx++) /* (CR 7453) was VCO8DIV4) */
{
/* grab the low-edge */
low_edge = _HAMARO_TUNER_CX24108_hardware_vcoedge_low(nim,vcoidx,&first_edge);
nim->pll_frequency = 0UL;
/* nim->tuner.cx24108.vco_edge[vcoidx].lower = 0UL;*/ /* cr 7452 */
if (low_edge != 0UL) nim->tuner.cx24108.vco_edge[vcoidx].lower = low_edge;
if (low_edge == 0UL) return(False);
/* grab the high-edge */
high_edge = _HAMARO_TUNER_CX24108_hardware_vcoedge_high(nim,vcoidx,low_edge,first_edge,nim->tuner.cx24108.vco_len[vcoidx]);
nim->pll_frequency = 0UL;
/* nim->tuner.cx24108.vco_edge[vcoidx].upperthresh = 0UL;*/ /* cr 7452 */
if (high_edge != 0UL) nim->tuner.cx24108.vco_edge[vcoidx].upperthresh = high_edge;
if (high_edge == 0UL) return(False);
}
/* restore the CPC setting */
nim->tuner.cx24108.CPCCurrent = CPCCurrent;
/* (CR 7453) vco edges calculated for DIV2 are valid for DIV4 edges */
nim->tuner.cx24108.vco_edge[HAMARO_VCO6D4].lower = nim->tuner.cx24108.vco_edge[HAMARO_VCO6D2].lower/2UL;
nim->tuner.cx24108.vco_edge[HAMARO_VCO6D4].upperthresh = nim->tuner.cx24108.vco_edge[HAMARO_VCO6D2].upperthresh/2UL;
nim->tuner.cx24108.vco_edge[HAMARO_VCO7D4].lower = nim->tuner.cx24108.vco_edge[HAMARO_VCO7D2].lower/2UL;
nim->tuner.cx24108.vco_edge[HAMARO_VCO7D4].upperthresh = nim->tuner.cx24108.vco_edge[HAMARO_VCO7D2].upperthresh/2UL;
nim->tuner.cx24108.vco_edge[HAMARO_VCO8D4].lower = (nim->tuner.cx24108.vco_edge[HAMARO_VCO8D2].lower/2UL);
nim->tuner.cx24108.vco_edge[HAMARO_VCO8D4].upperthresh = (nim->tuner.cx24108.vco_edge[HAMARO_VCO8D2].upperthresh/2UL);
/* re-cal bp after vco edges detected */
_HAMARO_TUNER_CX24108_calc_bp(nim);
/* adjust pre-set vco's if below 2150/2 */
_HAMARO_TUNER_CX24108_adjust(nim);
return(True);
} /* _HAMARO_TUNER_CX24108_hardware_vcoedges() */
/*******************************************************************************************************/
/* _HAMARO_TUNER_CX24108_hardware_vcoedge_low() */
/*******************************************************************************************************/
unsigned long _HAMARO_TUNER_CX24108_hardware_vcoedge_low( /* find vco's low edge */
HAMARO_NIM *nim, /* nim pointer */
int vcoidx, /* vco idx number to find edge of */
unsigned long *first_edge) /* returns computed "middle" of detected vco */
{
int done = False;
int counter;
int pllerrcnt = 0;
int loopcnt = 0;
unsigned long mid_pt;
unsigned long lowest_pt;
unsigned long test_pt;
unsigned long ulTemp; /* unused: holds return state only */
BOOL locked;
BOOL fm;
mid_pt = (nim->tuner.cx24108.vco_edge[vcoidx].upperthresh - nim->tuner.cx24108.vco_edge[vcoidx].lower)/2UL;
mid_pt += nim->tuner.cx24108.vco_edge[vcoidx].lower;
/* use 2mA CPC current for low edge detection */
nim->tuner.cx24108.CPCCurrent = HAMARO_CX24108_CPC_LOW;
/* find the "mid-point" of vco to test edge of. (This MUST lock!) (CR 7452 changed below line to return 1 on fail) */
if (_HAMARO_TUNER_CX24108_first_edgelock(nim,&mid_pt,&locked,(HAMARO_VCOSET)vcoidx) == False) return(HAMARO_TUNER_VCOERROR_ONE);
*first_edge = mid_pt;
/* we've locked first time into the "middle" of a good band, so start the search */
lowest_pt = mid_pt;
while ((locked == True) && (loopcnt < HAMARO_CX24108_MAX_LOOP))
{
loopcnt++;
/* adjust lowest pt. with big jumps, set freq, get lock status */
/* when lock is lost, this is max bounds */
lowest_pt -= (HAMARO_CX24108_NOMSTEP*HAMARO_CX24108_EDGESTEP);
fm = _HAMARO_TUNER_CX24108_freq_manual(nim,lowest_pt);
ulTemp = _HAMARO_TUNER_CX24108_vcoband_manual(nim,vcoidx);
if (_HAMARO_TUNER_CX24108_pll_status(nim,&locked) == False) pllerrcnt++;
}
/* Check if hardware is stuck. */
if (loopcnt == HAMARO_CX24108_MAX_LOOP)
{
return(HAMARO_TUNER_VCOERROR_ZERO);
}
/* recalc mid-pt */
mid_pt = lowest_pt + (HAMARO_CX24108_NOMSTEP*HAMARO_CX24108_EDGESTEP);
/* mid_pt is highest last known lock position; lowest_pt is past known boundary, so we have binary search bounds */
/* so perform bin search to catch edge */
done = False;
counter = 0;
while (done == False)
{
test_pt = mid_pt - ((mid_pt-lowest_pt)/2UL);
fm = _HAMARO_TUNER_CX24108_freq_manual(nim,test_pt);
ulTemp = _HAMARO_TUNER_CX24108_vcoband_manual(nim,vcoidx);
if (_HAMARO_TUNER_CX24108_pll_status(nim,&locked) == False) pllerrcnt++;
if (locked == True) mid_pt = test_pt;
else lowest_pt = test_pt;
/* bail if we're within the ballpark of the edge */
if ((mid_pt-lowest_pt) < HAMARO_CX24108_MINHILOWDIST) return(mid_pt);
counter++;
if (counter > HAMARO_CX24108_MAX_EDGEDIV) done = True;
}
/* not successful finding middle-point of band (i.e. could not start) */
return(HAMARO_TUNER_VCOERROR_ZERO);
} /* _HAMARO_TUNER_CX24108_hardware_vcoedge_low() */
/*******************************************************************************************************/
/* _HAMARO_TUNER_CX24108_hardware_vcoedge_high() */
/*******************************************************************************************************/
unsigned long _HAMARO_TUNER_CX24108_hardware_vcoedge_high( /* find vco's low edge */
HAMARO_NIM *nim, /* nim pointer */
int vcoidx, /* vco idx number to find edge of */
unsigned long low_edge, /* low-edge found (used in high-edge start calc) */
unsigned long first_edge, /* first-edge found when low-edge detected (used in high-edge calc) */
unsigned long vco_len) /* estimated length of this vco */
{
int done = False;
int counter;
int pllerrcnt = 0;
int loopcnt = 0;
unsigned long mid_pt;
unsigned long highest_pt;
unsigned long test_pt;
unsigned long ulTemp; /* unused: holds return state only */
BOOL locked = True;
BOOL fm;
/* if neither potential edge is valid, we have a serious error. (save and bail) */
if ((low_edge <= HAMARO_MAX_TUNER_VCOERROR && first_edge <= HAMARO_MAX_TUNER_VCOERROR) || (vco_len == 0)) return(HAMARO_TUNER_VCOERROR_TWO);
/* use 3mA CPC current for high edge detection */
nim->tuner.cx24108.CPCCurrent = HAMARO_CX24108_CPC_HIGH;
/* Use a known good start point to do the high edge search. */
mid_pt = first_edge;
/* we've locked first time into the middle of a good band, so start the search */
highest_pt = mid_pt;
while ((locked == True) && (loopcnt < HAMARO_CX24108_MAX_LOOP))
{
loopcnt++;
/* adjust highest pt., set freq, get lock status */
highest_pt += (HAMARO_CX24108_NOMSTEP*HAMARO_CX24108_EDGESTEP);
fm = _HAMARO_TUNER_CX24108_freq_manual(nim,highest_pt);
ulTemp = _HAMARO_TUNER_CX24108_vcoband_manual(nim,vcoidx);
if (_HAMARO_TUNER_CX24108_pll_status(nim,&locked) == False) pllerrcnt++;
}
/* Check if hardware is stuck. */
if (loopcnt == HAMARO_CX24108_MAX_LOOP)
{
return(HAMARO_TUNER_VCOERROR_ZERO);
}
/* recalc mid-pt (so edge is between mid_pt and highest_pt) */
mid_pt = highest_pt - (HAMARO_CX24108_NOMSTEP*HAMARO_CX24108_EDGESTEP);
/* now we have our binary search bounds, so perform bin search to catch edge */
done = False;
counter = 0;
while (done == False)
{
test_pt = mid_pt + ((highest_pt-mid_pt)/2UL);
fm = _HAMARO_TUNER_CX24108_freq_manual(nim,test_pt);
ulTemp = _HAMARO_TUNER_CX24108_vcoband_manual(nim,vcoidx);
if (_HAMARO_TUNER_CX24108_pll_status(nim,&locked) == False) pllerrcnt++;
if (locked == True) mid_pt = test_pt;
else highest_pt = test_pt;
/* bail if we're within the ballpark of the edge */
if ((highest_pt-mid_pt) < HAMARO_CX24108_MINHILOWDIST)
{
done = True;
return(mid_pt);
}
counter++;
if (counter > HAMARO_CX24108_MAX_EDGEDIV) done = True;
}
/* not successful finding middle-point of band (i.e. could not start) */
return(HAMARO_TUNER_VCOERROR_ZERO);
} /* _HAMARO_TUNER_CX24108_hardware_vcoedge_high() */
/*******************************************************************************************************/
/* _HAMARO_TUNER_CX24108_vcoband_manual() */
/*******************************************************************************************************/
unsigned long _HAMARO_TUNER_CX24108_vcoband_manual( /* function to manually set the tuner band selection programming bits */
HAMARO_NIM *nim, /* pointer to nim */
int vcoband) /* vco number (0..10) to set tuner to */
{
int err = 0;
unsigned long ulRegVal;
unsigned int vcodivbin;
unsigned int bandbin;
static HAMARO_VCODIV _vcodiv[] = {HAMARO_VCODIV2,HAMARO_VCODIV2,HAMARO_VCODIV2,HAMARO_VCODIV2,HAMARO_VCODIV2,HAMARO_VCODIV2,HAMARO_VCODIV2,HAMARO_VCODIV2,HAMARO_VCODIV4,HAMARO_VCODIV4,HAMARO_VCODIV4};
static unsigned int _bandbin[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x20,0x40,0x80};
static int _vcodivbin[] = {-1,-1,1,-1,0}; /* 2=0x01, 4=0x00 */
/* disallow invalid band setting */
if (vcoband >= HAMARO_CX24108_VCOEDGES) return(0UL);
vcodivbin = (unsigned int)_vcodivbin[_vcodiv[vcoband]];
bandbin = _bandbin[vcoband];
ulRegVal = vcodivbin;
ulRegVal <<= 9;
ulRegVal |= bandbin;
if (_HAMARO_TUNER_CX24108_io(nim,HAMARO_CX24108_BAND_PROG,ulRegVal) == False) err++;
return(ulRegVal);
} /* _HAMARO_TUNER_CX24108_vcoband_manual() */
/*******************************************************************************************************/
/* _HAMARO_TUNER_CX24108_first_edgelock() */
/*******************************************************************************************************/
BOOL _HAMARO_TUNER_CX24108_first_edgelock( /* Function to find the first-lock position of vco edges detect */
HAMARO_NIM *nim, /* pointer to nim */
unsigned long *mid_pt, /* point at which initial edge detection will start */
BOOL *locked, /* returns True if locked, (if False, error: failure to find initial edge) */
HAMARO_VCOSET vcoband) /* vco band number being scanned */
{
int i;
if (__HAMARO_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 < HAMARO_CX24108_MAX_FIRSTEDGE+1 ; i++)
{
*mid_pt += (i * (HAMARO_CX24108_NOMSTEP * HAMARO_CX24108_EDGESTEP));
if (__HAMARO_TUNER_CX24108_first_edgeone(nim,mid_pt,locked,vcoband) == True) return(True);
*mid_pt -= (i * (HAMARO_CX24108_NOMSTEP * HAMARO_CX24108_EDGESTEP));
*mid_pt -= (i * (HAMARO_CX24108_NOMSTEP * HAMARO_CX24108_EDGESTEP));
if (__HAMARO_TUNER_CX24108_first_edgeone(nim,mid_pt,locked,vcoband) == True) return(True);
*mid_pt += (i * (HAMARO_CX24108_NOMSTEP * HAMARO_CX24108_EDGESTEP));
}
/* unable to find a reasonable vco edge */
HAMARO_DRIVER_SET_ERROR(nim,HAMARO_TUNEREDGE);
return(False);
} /* _HAMARO_TUNER_CX24108_first_edgelock() */
/*******************************************************************************************************/
/* __HAMARO_TUNER_CX24108_first_edgeone() */
/*******************************************************************************************************/
BOOL __HAMARO_TUNER_CX24108_first_edgeone( /* Function to find the first-lock position of vco edges detect */
HAMARO_NIM *nim, /* pointer to nim */
unsigned long *mid_pt, /* point at which initial edge detection will start */
BOOL *locked, /* returns True if locked, (if False, error: failure to find initial edge) */
HAMARO_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) */
unsigned long bm; /* band manual return */
/* change freq, test lock */
if (_HAMARO_TUNER_CX24108_freq_manual(nim,*mid_pt) == False) return(False);
bm = _HAMARO_TUNER_CX24108_vcoband_manual(nim,vcoidx);
if (_HAMARO_TUNER_CX24108_pll_status(nim,locked) == False) return(False);
if (*locked == True)
{
/* successful tune, and pll lock */
return(True);
}
return(False);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -