📄 radiosub.c
字号:
(*pwCurFreq) = DisplayFreqToRf(g_JapanWideFmBandList[i+1].wBandLo);
else
(*pwCurFreq) = wRfBandHigh; // ie: DisplayFreqToRf(g_JapanWideFmBandList[i].wBandHi);
byResult = LVLS_FREQ_JUMP_ERR;
}
}
}
}
// Check against hardware limit
if ( (*pwCurFreq<g_wHwRfLow) || (*pwCurFreq>g_wHwRfHigh) )
{
byResult = LVLS_UNREACHABLE_FREQ_ERR;
(*pwCurFreq<g_wHwRfLow)?(*pwCurFreq=g_wHwRfLow):(*pwCurFreq=g_wHwRfHigh);
}
return(byResult);
} // End CheckRfLimit
/* ************************************************************************************************
*
* Function: ScanFmRoutine
*
* Authors: Hung van Le
* Purpose: Scan FM band for station
* Input:
* int iDir: Scan direction (iDir = 1: scan up, -1: scan down)
* WORD wFmBandLow, WORD wFmBandHigh: RF-frequency range for scanning (in 10 kHz-unit)
* Output: Status as defined in LvErr.h
* Global: g_byScanLevel: the field strength level to accept/reject a station (must be set before invoking this routine)
* g_byStnFlag: STN_VALID flag to determine the initial start frequency: when this flag is set (we're at a valid station)
* extra offset will be added to avoid finding the same station.
* g_byHwFlag1: HF1_NEG_IF_PHASE flag for the IF phase (the scan search for IF edge, the phase indicates which edge (Positive/Negative) is valid)
* g_wLastSetRF: the RF frequency (change during scanning)
* g_wLastMsrRF: the measured RF frequency (change during scanning)
* Comments: The chip should be correctly set up before invoking this routine (Measure mode, mute , stereo ...)
*
* ************************************************************************************************
* Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
BYTE ScanFmRoutine(int iDir, WORD wFmBandLow, WORD wFmBandHigh)
{
#define SCFM_FROMSTATION_STEP ((WORD)20) // 200 kHz - Step size to step away from a station
#define SCFM_NOSTATION_STEP ((WORD)10) // 100 kHz - Step size when a station is not found
#define SCFM_DISPLAY_DISTANCE ((WORD)85) // 850 kHz - Update display distance
#define SCFM_SCANSTEP ((int)8) // 80 kHz - scan step (10 kHz-unit)
#define SCFM_IFSWING ((int)3500) // 35 kHz - IF swing (10 Hz-unit)
#define SCFM_PRECISION QSSF_PRECISION_LOW // precision level use by ScanSetFreq
BYTE byResult;
WORD wIfFreq, wIfFreq2;
BOOL bCorrectEdge;
int iStepFreq, iIfDif;
int iIfSwing;
BYTE byMsrFs, bySwFsLevel, byDispCnt;
// Init var.
byResult = LVLS_NO_ERROR;
wIfFreq =0;
if (g_byStnFlag & STN_VALID) // Valid station
iStepFreq = SCFM_FROMSTATION_STEP; // Step away from current stattion
else
iStepFreq = 0;
g_byStnFlag &= (~STN_VALID); // No valid station now
// Scan routine uses bySwFsLevel, i32ScanStepHz, i32IfSwingHz, which are derived from g_byScanLevel
// Adjust the scan level because the radio chip can not measure it quickly
bySwFsLevel = g_byScanLevel;
if (g_byScanLevel > 0)
bySwFsLevel--; // Leave 0 at 0, convert 1..7 to 0..6
if (bySwFsLevel>3)
bySwFsLevel--; // Convert scan level 7/6/5 to 5/4/3 (hardware measuring!!!)
// Determine sign of the IF swing (depend on the scan direction and the IF phase)
iIfSwing = SCFM_IFSWING * iDir;
if ( g_byHwFlag1 & HF1_NEG_IF_PHASE) // Negative IF phase
iIfSwing = -iIfSwing;
// Scan loop
byDispCnt = 0;
while ( (g_byStnFlag & STN_VALID)==0 ) // While not valid station
{
// Calculate the new frequency
g_wLastSetRF += (iStepFreq*iDir);
// Check frequency
byResult = CheckRfLimit(&g_wLastSetRF, wFmBandLow, wFmBandHigh, iDir);
if (byResult != LVLS_NO_ERROR)
{
wIfFreq = 0;
if (byResult != LVLS_FREQ_JUMP_ERR)
{
// Set frequency to valid one
ScanSetFreq(g_wLastSetRF, QSSF_PRECISION_HIGH);
goto return_ScanFmRoutine;
}
}
// Set the frequency
byResult = ScanSetFreq(g_wLastSetRF, SCFM_PRECISION);
if (byResult != LVLS_NO_ERROR)
goto return_ScanFmRoutine;
// Callback - report current frequency
byDispCnt++;
//if (byDispCnt>9)
if (byDispCnt>1)
{
byResult = CallBack(CRSN_SCAN_UPD);
if (byResult != LVLS_NO_ERROR)
goto return_ScanFmRoutine;
byDispCnt = 0;
}
// Check 1: field strength should be sufficient
if ( bySwFsLevel>0 )
{
//DelayUs(DLT_5ms); // The hardware fieldstrength measuring circuitry is not very fast, give it sometimes
byMsrFs = GetFmFieldStrength();
if ( byMsrFs < bySwFsLevel )
{
DelayUs(DLT_5ms); // The hardware fieldstrength measuring circuitry is not very fast, give it sometimes
byMsrFs = GetFmFieldStrength();
}
if ( byMsrFs < bySwFsLevel )
{
iStepFreq = SCFM_SCANSTEP;
wIfFreq = 0;
continue;
}
}
// Measure the IF frequency at current point
byResult = MeasureFrequency(CO_IF_OSC, LV_MSR_TIME_8ms, &wIfFreq2);
if (byResult != LVLS_NO_ERROR)
goto return_ScanFmRoutine;
// Checking the IF edge when we have the 1st IF
bCorrectEdge = FALSE;
if (wIfFreq != 0)
{
iIfDif = (int)wIfFreq-(int)wIfFreq2;
if (iIfSwing > 0)
{
if ( iIfDif >= iIfSwing ) // found edge
bCorrectEdge = TRUE;
}
else
{
if ( iIfDif <= iIfSwing ) // found edge
bCorrectEdge = TRUE;
}
}
// Move current point to 1st point for next time
wIfFreq = wIfFreq2;
// Check if we have a correct IF-edge
if ( !bCorrectEdge )
{
iStepFreq = SCFM_SCANSTEP;
continue;
}
// Final step: pinpoint the station if field strength is sufficient
if ( bySwFsLevel>0 )
{
byMsrFs = GetFmFieldStrength();
if ( byMsrFs < bySwFsLevel )
{
iStepFreq = SCFM_SCANSTEP;
continue;
}
}
// Last update before FindFmStation
byResult = CallBack(CRSN_SCAN_UPD);
if (byResult != LVLS_NO_ERROR)
goto return_ScanFmRoutine;
// Pinpoint the station
if ( FindFmStation() )
g_byStnFlag |= STN_VALID;
else
{
// Reset scan variable for next scan when not found
iStepFreq = SCFM_NOSTATION_STEP;
wIfFreq =0;
continue;
}
// Verfy that we have the station with correct field strength
if ( g_byScanLevel > 0 )
{
byMsrFs = GetFmFieldStrength();
if ( byMsrFs < g_byScanLevel )
{
g_byStnFlag &= (~STN_VALID); // Wrong field strength
iStepFreq = SCFM_SCANSTEP;
}
}
} // End ScanLoop
return_ScanFmRoutine:
if (byResult == LVLS_NO_ERROR)
{
// We found a station, extra verification when the found station is at 50 kHz grid
MeasureFrequency(CO_RF_OSC, LV_MSR_TIME_32ms, &wIfFreq); // Update g_wLastMsrRF
wIfFreq = GetDisplayFrequency(5); // Temp. use wIfFreq to store current display frequency, aligned at 50 kHz
if ( (wIfFreq % 10) == 5 ) // Display frequency end at 50 kHz?
{
// Determine the station frequency again
MeasureFrequency(CO_IF_OSC, LV_MSR_TIME_32ms, &wIfFreq); // IF
// Compensate RF to get with the last measured IF
// Calculate the delta IF
iIfDif = (int)wIfFreq - (int)DEFAULT_IF_FREQ;
if ( g_byHwFlag1 & HF1_NEG_IF_PHASE) // Apply IF-sign
iIfDif = -iIfDif; // Negative IF phase
// Compensate RF to get the desired IF (IF in 10 Hz, RF in 10 kHz unit)
// g_wLastMsrRF is updated above
g_wLastMsrRF = (int)g_wLastMsrRF + (iIfDif/1000);
}
}
return(byResult);
} // End ScanFmRoutine
/* ************************************************************************************************
*
* Function: FindFmStation
*
* Authors: Hung van Le
* Purpose: Try to find a FM station
* Input: None
* Output: TRUE : station found
* FALSE: no station found
* Global: g_byHwFlag1: HF1_NEG_IF_PHASE flag for the IF phase
* g_wLastMsrRF: the measured RF frequency (compensated for display frequency calculation)
* Comments: - A FM station is characterized by the IF-edge of +/- 45 degree (positive/negative IF).
* When we have the correct edge, the station can be pinpointed by using equation RF1 +/- IF1 = RF2 +/- IF2
* (+ or - depends on the IF-phase)
*
* - When a station is found, the RF will be compensated with dIF:
* To avoid wrong display frequency, we have to correct the RF-frequency according to the measured IF-frequency.
* When the IF-phase is negative, we have relation:
* DisplayFreq = RF - IF (for positive phase the equation is DisplayFreq = RF + IF)
* When we find a station, the display frequency should be
* DisplayFreq = RF' - MeasuredIF
* where MeasuredIF = CalibratedIF + dIF.
* or dIF = MeasuredIF - CalibratedIF (dIF can be negative and is 0 when the RF is correctly tuned)
* so RF' = RF + dIF
* For example when the CalibratedIF is 110 kHz, and we find a station with 100 kHz as last measured IF,
* dIF = 100 - 110 = -10 kHz
* When the IF phase is negative, The RF' is then RF' = RF + 10 kHz
*
* - This routine can also be used to validate the FM station
*
* ************************************************************************************************
* Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
BOOL FindFmStation(void)
{
// #define FFS_IF_MARGIN 1500 // in 10 Hz unit
#define FFS_IF_MARGIN 2500 // in 10 Hz unit
BYTE byLoopCnt;
WORD wCurFM;
WORD wCurIF;
int iDifIF;
// Determine current IF
MeasureFrequency(CO_IF_OSC, LV_MSR_TIME_32ms, &wCurIF);
if ( (wCurIF < (DEFAULT_IF_FREQ-FFS_IF_MARGIN)) || (wCurIF >(DEFAULT_IF_FREQ+FFS_IF_MARGIN)) )
{
// Determine the current FM frequency (always measure RF for correcting it here after)
MeasureFrequency(CO_RF_OSC, LV_MSR_TIME_32ms, &wCurFM);
// Enter find station point loop if IF-frequency is not in OK range
byLoopCnt = 4;
do
{
byLoopCnt--;
if (byLoopCnt == 0)
return(FALSE);
// Calculate the delta IF
iDifIF = (int)wCurIF - (int)DEFAULT_IF_FREQ;
if ( g_byHwFlag1 & HF1_NEG_IF_PHASE ) // Apply IF-sign
iDifIF = -iDifIF; // Negative IF phase
wCurFM = (int)wCurFM + (iDifIF/1000); // Compensate RF to get the desired IF (IF in 10 Hz, RF in 10 kHz unit)
if ( ScanSetFreq(wCurFM, QSSF_PRECISION_HIGH) != LVLS_NO_ERROR )
return(FALSE);
MeasureFrequency(CO_IF_OSC, LV_MSR_TIME_32ms, &wCurIF);
} while ( (wCurIF<(DEFAULT_IF_FREQ-FFS_IF_MARGIN)) || (wCurIF>(DEFAULT_IF_FREQ+FFS_IF_MARGIN)) );
}
return(TRUE);
} // End FindFmStation
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -