📄 radiosub.c
字号:
/************************************************************************
*
* Copyright(c) 2004 ItoM BV
* All Rights Reserved.
*
* LV2400x evaluation kit: Radio implementations
* File name: RadioSub.c
* Several subroutines to be used by Radio.c
*
*************************************************************************/
#include <stdio.h>
#include "common.h"
#include "Lv24Ekit.h"
/*-------------------------------------------------------------------
Local data
-------------------------------------------------------------------*/
// Structure for band limit
typedef struct
{
WORD wBandLo; // Band low limit (in 10 kHz)
WORD wBandHi; // Band high limit (in 10 kHz)
} BAND_LIMIT_ST;
// ----- Japan Wide limit list
BAND_LIMIT_ST _rom g_JapanWideFmBandList[] =
{
{ (7600-15), (9000+15), }, // Base Japan FM limit 76-90 MHz
{ ( 9575-15), ( 9575+15), }, // Channel 1: 95.75 MHz
{ (10175-15), (10175+15), }, // Channel 2: 101.75 MHz
{ (10775-15), (10775+15), }, // Channel 3: 107.75 MHz
};
#define JAPANWIDE_FMBAND_LSIZE (sizeof(g_JapanWideFmBandList)/sizeof(g_JapanWideFmBandList[0]))
/*-------------------------------------------------------------------
Code
-------------------------------------------------------------------*/
/* ************************************************************************************************
*
* Function: MeasureFrequency
*
* Authors: Hung van Le
* Purpose: Virtualize the I3W frequency measuring
* Input:
* WORD wSource: source to be measured. See definitions in I3wChip.h (MeasureFrequency, SetUpChipMode)
* DWORD dwMeasureTimeUs: measure time in us
* PDWORD pdwFreqHz: Buffer to receive the measured frequency (in Hz)
* Output: Status as defined in LvErr.h
* Comments: None
*
* ************************************************************************************************
* Copyright (c) 2002-2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
BYTE MeasureFrequency(WORD wSource, DWORD dwMeasureTimeUs, PWORD pwFreq)
{
// Measure frequency of specified source
BYTE byResult;
WORD wCfg;
// Select correct oscillator output and enable measuring mode
wCfg = SetUpChipMode(wSource | CHIP_MEASURE_MODE);
// Measuring
byResult = CountPulse(dwMeasureTimeUs, pwFreq);
// Restore chip config
SetUpChipMode(wCfg);
return(byResult);
} // End MeasureFrequency
/* ************************************************************************************************
*
* Function: DisplayFreqToRf
*
* Authors: Hung van Le
* Purpose: Convert the display frequency to RF-frequency
* Input:
* WORD wDisp: the display frequency i 10 kHz unit (example 87.5 MHz is 8750)
* Output: Status as defined in LvErr.h
* Global:
* g_byHwFlag1: HF1_NEG_IF_PHASE-flag for IF phase
* Comments: The display frequency has 2 components: The RF and IF frequency
* The radio hardware has 2 separated circuitries to deal with these components.
* The IF frequency is set once during radio hardware initialization.
* Changing RF frequency will tune the radio hardware to another station
* When the IF has negative phase:
* RF = DisplayFrequency + CalibratedIF
* When the IF has positive phase:
* RF = DisplayFrequency - CalibratedIF
*
* ************************************************************************************************
* Copyright (c) 2002-2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
WORD DisplayFreqToRf(WORD wDisp)
{
#ifdef SUPPORT_AMFM
WORD wIfFreq;
if ( (g_byStnFlag & STN_AM_MODE) == STN_AM_MODE )
wIfFreq = DEFAULT_AM_IF_FREQ/100; // AM-RF in 1 kHz, IF in 10 Hz: convert IF to 1 kHz
else
wIfFreq = DEFAULT_IF_FREQ/1000; // FM-RF in 10 kHz, IF in 10 Hz: convert IF to 10 kHz
// Negative IF phase
if ( g_byHwFlag1 & HF1_NEG_IF_PHASE)
return(wDisp + wIfFreq); // RF = display + IF
// Positive IF
return(wDisp - wIfFreq); // RF = display - IF
#endif // SUPPORT_AMFM
#ifdef FM_ONLY
// Negative IF phase
if ( g_byHwFlag1 & HF1_NEG_IF_PHASE)
return(wDisp + DEFAULT_IF_FREQ/1000); // RF (in 10 kHz) = display + IF (remark: IF in 10 Hz)
// Positive IF
return(wDisp - DEFAULT_IF_FREQ/1000); // RF (in 10 kHz) = display - IF
#endif //FM_ONLY
} // End DisplayFreqToRf
/* ************************************************************************************************
*
* Function: RfToDisplayFreq
*
* Authors: Hung van Le
* Purpose: Convert the RF-frequency to display frequency
* Input:
* WORD wRf: the RF-frequency i 10 kHz unit (example 87.5 MHz is 8750)
* Output: Status as defined in LvErr.h
* Global:
* g_byHwFlag1: HF1_NEG_IF_PHASE-flag for IF phase
* Comments: See also DisplayFreqToRf
* We use following equation to calculate the display frequency:
* When the IF has negative phase:
* DisplayFrequency = RF - CalibratedIF
* When the IF has positive phase:
* DisplayFrequency = RF + CalibratedIF
*
* ************************************************************************************************
* Copyright (c) 2002-2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
WORD RfToDisplayFreq(WORD wRf)
{
#ifdef SUPPORT_AMFM
WORD wIfFreq;
if ( (g_byStnFlag & STN_AM_MODE) == STN_AM_MODE )
wIfFreq = DEFAULT_AM_IF_FREQ/100; // AM-RF in 1 kHz, IF in 10 Hz: convert IF to 1 kHz
else
wIfFreq = DEFAULT_IF_FREQ/1000; // FM-RF in 10 kHz, IF in 10 Hz: convert IF to 10 kHz
// Negative IF phase
if ( g_byHwFlag1 & HF1_NEG_IF_PHASE)
return(wRf - wIfFreq); // display = RF - IF
// Positive IF
return(wRf + wIfFreq); // display = RF + IF
#endif // SUPPORT_AMFM
#ifdef FM_ONLY
// Negative IF phase
if ( g_byHwFlag1 & HF1_NEG_IF_PHASE)
return(wRf - DEFAULT_IF_FREQ/1000); // display = RF - IF
// Positive IF
return(wRf + DEFAULT_IF_FREQ/1000); // display = RF + IF
#endif // FM_ONLY
} // End DisplayFreqToRf
/* ************************************************************************************************
*
* Function: CheckRfLimit
*
* Authors: Hung van Le
* Purpose: Check input frequency against the specified RF-limit in dwBandLow/dwBandHigh,
* Wrap the input frequency if bWrapFreq is true
* The frequency will be checked against the hardware limit (stored in m_dwHwRfLow/m_dwHwRfHigh)
* Input:
* PWORD pwCurFreq: pointer to frequency to be checked (in 10 kHz unit)
* WORD wBandLow, WORD wBandHigh: the band limit in 10 kHz
* iAdjust: adjust pwCurFreq when error
* <=0: adjust for down scanning
* 1: adjust for up scanning
* 2: no adjustment, wrap high to low, low to high (default wrapping is low to low, high to high)
*
* Output: Status as defined in LvErr.h
* LVLS_FREQ_JUMP_ERR is returned when adjustment is done.
* Global: g_wHwRfLow: the lower limit of hardware RF frequency
* g_wHwRfHigh: the upper limit of hardware RF frequency
* Comments: Scheme
* *pwCurFreq bWrapFreq New freq Status
* a) <wBandLow true wBandHigh No error
* b) false wBandLow Out of band error
* c) >wBandHigh true wBandLow No error
* d) false wBandHigh Out of band error
* e) Other cases X No change No error
* Extra check by (a), (c), (e)
* *pwCurFreq New freq Status
* <g_wHwRfLow g_wHwRfLow Error: Unreachable frequency
* >g_wHwRfHigh g_wHwRfHigh Error: Unreachable frequency
* Other cases No change No error (within hardware limit)
* ************************************************************************************************
* Copyright (c) 2002-2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
BYTE CheckRfLimit(PWORD pwCurFreq, WORD wRfBandLow, WORD wRfBandHigh, int iAdjust)
{
BYTE byResult;
BYTE i;
byResult = LVLS_NO_ERROR;
i=0; // Use i to enable JapanWide alignment
if (*pwCurFreq < wRfBandLow) // exceed lower limit
{
if (iAdjust == 2)
{
*pwCurFreq = wRfBandHigh; // No error by wrapping
}
else
{
*pwCurFreq = wRfBandLow;
byResult = LVLS_RFFREQ_ENDOFBAND_ERR;
}
i=1; // skip JapanWide alignment
}
else if (*pwCurFreq > wRfBandHigh) // exceed upper limit
{
if (iAdjust == 2)
{
*pwCurFreq = wRfBandLow; // No error by wrapping
}
else
{
*pwCurFreq = wRfBandHigh;
byResult = LVLS_RFFREQ_ENDOFBAND_ERR;
}
i=1; // skip JapanWide alignment
}
// Special handling for Japan-wide support: adjust the RF according to iAdjust and current RF frequency
if (i == 0) // Go on if JapanWide alignment is allowed
{
#ifdef SUPPORT_AMFM
if ( (g_byStnFlag & STN_AM_MODE) == STN_FM_MODE ) // Are we in FM mode?
{
if (g_byRegion == REGION_JAPAN_WIDE)
i=1;
}
#endif //SUPPORT_AMFM
#ifdef FM_ONLY
if (g_byRegion == REGION_JAPAN_WIDE)
i=1;
#endif //FM_ONLY
if (i != 0) // Japan Wide enabled
{
// Determine which limit band to use
for (i=0; i<(JAPANWIDE_FMBAND_LSIZE-1); i++)
{
if ( ((*pwCurFreq) > DisplayFreqToRf(g_JapanWideFmBandList[i].wBandLo)) &&
((*pwCurFreq) < DisplayFreqToRf(g_JapanWideFmBandList[i+1].wBandLo)) )
break; // found band
}
wRfBandLow = DisplayFreqToRf(g_JapanWideFmBandList[i].wBandLo);
wRfBandHigh = DisplayFreqToRf(g_JapanWideFmBandList[i].wBandHi);
if (iAdjust > 1) // Check frequency
{
if ( (*pwCurFreq) > wRfBandHigh )
{
byResult = LVLS_FREQ_IN_LIMIT_GAP_ERR;
(*pwCurFreq) = wRfBandHigh;
}
else if ( (*pwCurFreq) < wRfBandLow )
{
byResult = LVLS_FREQ_IN_LIMIT_GAP_ERR;
(*pwCurFreq) = wRfBandLow;
}
} // EndIf CheckFreq
else // Align the frequency
{
if ( (*pwCurFreq) > wRfBandHigh )
{
// Go to next band. Above code already make sure the we are always in the band, so no need to check
// for max. band
if (iAdjust == 1) // Align frequency for up scanning
{
if (i==(JAPANWIDE_FMBAND_LSIZE-1))
(*pwCurFreq) = DisplayFreqToRf(g_JapanWideFmBandList[i].wBandHi);
else
(*pwCurFreq) = DisplayFreqToRf(g_JapanWideFmBandList[i+1].wBandLo);
}
else // Align frequency for down scanning
(*pwCurFreq) = wRfBandHigh; // ie: DisplayFreqToRf(g_JapanWideFmBandList[i].wBandHi);
byResult = LVLS_FREQ_JUMP_ERR;
}
else if ( (*pwCurFreq) < wRfBandLow )
{
if (iAdjust == 1) // Align frequency for up scanning
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -