📄 tunealg.c
字号:
} // End InterpolateX
int InterpolateOscStep(WORD wY, WORD wX1, WORD wX2, WORD wY1, WORD wY2)
{
// Draw a line from (X1,Y1) to (X2,Y2) to calculate the X (ie the OSC-value) belongs to desired Y (ie the dwExpFreq)
// formula:
// x2 - x1
// step = (y - y1)---------
// y2 - y1
// The OscValue is then (x1+step)
INT32 iDeltaY;
INT32 sA,sB, sC;
iDeltaY = (INT32)wY2-(INT32)wY1;
if (iDeltaY == 0 )
return(0);
// return( (int)((((signed long)dwY - (signed long)dwY1) * ((int)wX2 - (int)wX1)) + (iDeltaY/2))/iDeltaY );
sA = (INT32)wY - (INT32)wY1;
sB = sA * ((int)wX2 - (int)wX1);
sB += (iDeltaY/2);
sC = sB/iDeltaY;
return((int)sC);
} // End InterpolateOscStep
BYTE InitTuningRfCapOsc(void)
{
WORD wCfg;
WORD wTmp;
// Select correct oscillator output and enable measuring mode
wCfg = SetUpChipMode(CO_RF_OSC | CHIP_MEASURE_MODE | CHIP_AFC_OFF);
// Determine the min/max RF frequency (hardware RF-limit)
// Set CAP/OSC at minimal value and measure the the minimal hardware RF
GetRfAtCapOsc(QSS_MIN_RFCAP, QSS_MIN_RFOSC, LV_MSR_TIME_32ms, &g_wHwRfLow);
// Set CAP/OSC at maximal value and measure the maximal hardware RF
GetRfAtCapOsc(QSS_MAX_RFCAP, QSS_MAX_RFOSC, LV_MSR_TIME_32ms, &g_wHwRfHigh);
// Init QSSF-data
// Determine the 2 points for CAP-low line and the OSC-low resolution
Qssf1.CoefLo = CalculateCoeff(g_wHwRfLow); // Point1_0: Cap=min, Osc=min)
GetRfAtCapOsc(QSS_MIN_RFCAP, QSS_MAX_RFOSC, LV_MSR_TIME_32ms, &wTmp);
Qssf1.CoefHi = CalculateCoeff(wTmp); // Point1_1: Cap=min, Osc=max)
// Determine the 2 points for CAP-high line and the OSC-high resolution
GetRfAtCapOsc(QSS_MAX_RFCAP, QSS_MIN_RFOSC, LV_MSR_TIME_32ms, &wTmp);
Qssf2.CoefLo = CalculateCoeff(wTmp); // Point2_0: Cap=max, Osc=min)
Qssf2.CoefHi = CalculateCoeff(g_wHwRfHigh); // Point2_0: Cap=max, Osc=max)
// Restore chip config
SetUpChipMode(wCfg);
// Error check
if ( g_wHwRfHigh <= g_wHwRfLow)
return(LVLS_INV_RFLIMIT_ERR);
return(LVLS_NO_ERROR);
} // End InitTuningRfCapOsc
BYTE GetRfAtCapOsc(WORD wCapValue, WORD wOscValue, DWORD dwMsrTimeUs, PWORD pwFreq)
{
WriteRfCap(wCapValue);
WriteRfOsc(wOscValue);
return(CountPulse(dwMsrTimeUs, pwFreq)); // Measure the RF
} // End GetRfAtCapOsc
BYTE ScanSetFreq(WORD wTuneFreq, BYTE byPrecisionLevel)
{
// iPrecisionLevel ScanSetFreq CalculateRfCapOsc
// QSSF_PRECISION_NONE WriteOsc No CAP verification
// QSSF_PRECISION_LOW WriteOsc CAP verification with 8ms measuring
// QSSF_PRECISION_MED FineTuning 8ms CAP verification with 32ms measuring
// QSSF_PRECISION_HIGH FineTuning 32ms CAP verification with 64ms measuring
BYTE byResult;
WORD wCapValue, wOscValue;
// Calculate Cap, Osc value
byResult = CalculateRfCapOsc(wTuneFreq, &wCapValue, &wOscValue, byPrecisionLevel);
// Write CAP value
if (byResult == LVLS_NO_ERROR)
{
if (GetRfCapValue() != wCapValue)
byResult = WriteRfCap(wCapValue);
}
// Fine tuning if precision needed
if (byResult == LVLS_NO_ERROR)
{
if (byPrecisionLevel==QSSF_PRECISION_MED)
{
byResult = FineTuneRfOsc(wTuneFreq, LV_MSR_TIME_8ms, wOscValue, FALSE);
}
else if (byPrecisionLevel==QSSF_PRECISION_HIGH)
{
byResult = FineTuneRfOsc(wTuneFreq, LV_MSR_TIME_32ms, wOscValue, FALSE);
}
else // byPrecisionLevel==QSSF_PRECISION_NONE or QSSF_PRECISION_LOW
{
// Just write the OscValue, (CapValue is already written by CalculateRfCapOsc
byResult = WriteRfOsc(wOscValue);
}
}
if (byResult != LVLS_NO_ERROR)
byResult = FineTuneRfOsc(wTuneFreq, LV_MSR_TIME_32ms, QSS_MIN_RFOSC, FALSE);
return(byResult);
} // End ScanSetFreq
/* ************************************************************************************************
*
* Function: FineTuneRfOsc
*
* Authors: Hung van Le
* Purpose: Validate and possibly correcting the calculated CAP/OSC
* Input:
* Output: Status as defined in LvErr.h
* Comments:
*
* ************************************************************************************************
* Copyright (c) 2002-2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
BYTE FineTuneRfOsc(WORD wRfFreq, DWORD dwMeasureTimeUs, WORD wExpOscValue, BYTE byNeedPrecision)
{
BYTE i;
BYTE byResult;
WORD wCapValue;
wCapValue = GetRfCapValue();
for (i=0; i<5; i++)
{
byResult = WriteRfCap(wCapValue);
if (byResult == LVLS_NO_ERROR)
{
byResult = LinTuneDac(wRfFreq, dwMeasureTimeUs, WriteRfOsc, wExpOscValue, QSS_MAX_RFOSC, byNeedPrecision);
wExpOscValue = QSS_MIN_RFOSC; // Change to minimun value for next approach
}
if ( byResult != LVLS_RFOSC_OUTOFLIMIT_ERR)
break;
if (g_wLastMsrRF < wRfFreq )
wCapValue++;
else
wCapValue--;
}
return(byResult);
} // End FineTuneRfOsc
BYTE CalculateRfCapOsc(WORD wFreq, PWORD pwCap, PWORD pwOsc, BYTE byPrecisionLevel)
{
// Calculate the CAP/OSC value for dwFreqHz (frequency in Hz)
WORD wCoeff, wCorFreq;
BYTE byRetry;
WORD wCap;
DWORD dwMsrTimeUs;
// TODO: Check if QSSF-data initialised
// if (m_pQssfData==NULL)
// return(LVLS_NO_SSF_DATA_ERR);
// calculate Coeff of desired frequency
wCoeff = CalculateCoeff(wFreq);
// Determine measuring deviation
if (byPrecisionLevel==QSSF_PRECISION_NONE)
{
dwMsrTimeUs = 0;
wCorFreq = 0;
}
else if (byPrecisionLevel==QSSF_PRECISION_LOW)
{
dwMsrTimeUs = LV_MSR_TIME_8ms;
wCorFreq = 3; // (128 Hz * 256)/10 kHz (128Hz: fault by 8ms, 256: RF divider factor, 10kHz:RF unit
}
else if (byPrecisionLevel==QSSF_PRECISION_MED)
{
dwMsrTimeUs = LV_MSR_TIME_32ms;
wCorFreq = 0; // (32 Hz * 256)/10 kHz (32Hz: fault by 32ms, 256: RF divider factor, 10kHz:RF unit
}
else //if (byPrecisionLevel==QSSF_PRECISION_HIGH)
{
dwMsrTimeUs = LV_MSR_TIME_64ms;
wCorFreq = 0; // (16 Hz * 256)/10 kHz (16Hz: fault by 64ms, 256: RF divider factor, 10kHz:RF unit
}
//wCorFreq *= GetDividerFactor();
//wCorFreq /= 10000; //@@@ 10 kHz unit for RF
// Derive CAP from low data
wCap = InterpolateX( wCoeff, QSS_MIN_RFCAP, QSS_MAX_RFCAP, Qssf1.CoefLo, Qssf2.CoefLo);
// Calculate OSC value
byRetry = 3;
WriteRfOsc(QSS_MIN_RFOSC); // Kep OSC at fixed value during CAP calculation
while (byRetry)
{
WORD wCoefLo, wCoefHi, wCoefRange, wCoefReal, wCoefCor;
WORD wMsrFreq;
// Get coefficient of calculated CAP from low Qfm-Data
wCoefLo = InterpolateY(wCap, QSS_MIN_RFCAP, QSS_MAX_RFCAP, Qssf1.CoefLo, Qssf2.CoefLo);
// Get coefficient of calculated CAP from high Qfm-Data
wCoefHi = InterpolateY(wCap, QSS_MIN_RFCAP, QSS_MAX_RFCAP, Qssf1.CoefHi, Qssf2.CoefHi);
// Calculate range
wCoefRange = wCoefLo - wCoefHi; // vCoefLo should be greater than vCoefHi
// Verify CAP value: Write CAP, OSC and measure the frequency
if ( WriteRfCap(wCap) == LVLS_NO_ERROR)
{
// Determine the real coefficient of this CAP
if (byPrecisionLevel != QSSF_PRECISION_NONE)
{
CountPulse(dwMsrTimeUs, &wMsrFreq);
wCoefReal = CalculateCoeff(wMsrFreq);
if (wCorFreq > 0)
wCoefCor = wCoefReal - CalculateCoeff(wMsrFreq+wCorFreq);
else
wCoefCor = 0;
}
else
{
wCoefReal = wCoefLo;
wCoefCor = 0;
}
// Do we have the correct CAP
if ( (wCoeff<=(wCoefReal+wCoefCor)) && (wCoeff>=(wCoefReal-wCoefRange-wCoefCor)) )
{
// Derive the OSC value
*pwOsc = InterpolateX(wCoeff, QSS_MIN_RFOSC, QSS_MAX_RFOSC, wCoefReal+wCoefCor, wCoefReal-wCoefRange-wCoefCor);
// Done when approriate OSC value
if ( (*pwOsc>=QSS_MIN_RFOSC) && (*pwOsc<=QSS_MAX_RFOSC))
break;
}
// Not success, recalculate and try again
{
WORD wCapNew;
wCapNew = InterpolateX(wCoeff, wCap, QSS_MAX_RFCAP, wCoefReal, Qssf2.CoefLo);
if (wCapNew == wCap) // Interpolate doesn't work - stepping
{
if (wCoeff<wCoefReal)
wCap++; // Increase CAP to decrease vCoefReal
else
wCap--;
}
else
wCap = wCapNew;
}
// Retry
byRetry--;
}
else
{
// Write Cap failed - terminate
wCap = QSS_MAX_RFCAP; //xx
*pwOsc=QSS_MAX_RFOSC; //xx
break;
//iRetry=0;
}
} // EndWhile
*pwCap=wCap;
if (byRetry==0)
return(LVLS_CAPOSC_CALC_ERR);
return(LVLS_NO_ERROR);
} // End CalculateRfCapOsc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -