📄 directif.cpp
字号:
DWORD if_agc = 0;
//At this point we freeze AGCs and change RF_ATT_OFFSET to trigger the peak detector
//read the AGCs current value and freeze them
_p_registers->readDword(DIF_AGC_RF_CURRENT, &rf_agc);
_p_registers->readDword(DIF_AGC_IF_INT_CURRENT, &if_agc);
if(rf_agc >= 0xA000)
rf_agc = 0xC226FFFF;
if_agc = if_agc >>16;
//write the current RF_AGC value to the fixed gain setting
_p_registers->writeDword(DIF_AGC_CTRL_IF, if_agc);
_p_registers->writeDword(DIF_AGC_CTRL_RF, rf_agc|0xC2260000);
}
VOID DirectIF::FreezeAgcForNormalSenstivity()
{
DWORD rf_agc = 0;
DWORD if_agc = 0;
//At this point we freeze AGCs and change RF_ATT_OFFSET to trigger the peak detector
//read the AGCs current value and freeze them
_p_registers->readDword(DIF_AGC_RF_CURRENT, &rf_agc);
_p_registers->readDword(DIF_AGC_IF_INT_CURRENT, &if_agc);
if_agc = if_agc >>16;
//write the current RF_AGC value to the fixed gain setting
_p_registers->writeDword(DIF_AGC_CTRL_IF, if_agc);
_p_registers->writeDword(DIF_AGC_CTRL_RF, (rf_agc|0xC2260000));
}
VOID DirectIF::setIFAgcState(ULONG* p_agc_state)
{
_p_registers->writeDword(DIF_AGC_CTRL_IF, *p_agc_state);
}
VOID DirectIF::setRFAgcState(ULONG* p_agc_state)
{
_p_registers->writeDword(DIF_AGC_CTRL_RF, *p_agc_state);
}
// VOID DirectIF::DisableAgc()
// We are clearing these fields in Misc control to disable AGC
// FLD_DIF_RF_AGC_ENA, FLD_DIF_INT_AGC_ENA, FLD_DIF_IF_AGC_ENA
VOID DirectIF::DisableAgc()
{
DWORD misc_ctrl = 0;
_p_registers->readDword(DIF_MISC_CTRL, &misc_ctrl);
//misc_ctrl &= 0xC7FFFFFF;
misc_ctrl &= 0x02FFFFF1;
_p_registers->writeDword(DIF_MISC_CTRL, misc_ctrl);
}
// VOID DirectIF::DisableAgc()
// We are clearing these fields in Misc control to disable AGC
// FLD_DIF_RF_AGC_ENA, FLD_DIF_INT_AGC_ENA, FLD_DIF_IF_AGC_ENA
VOID DirectIF::EnableAgc()
{
DWORD misc_ctrl = 0;
_p_registers->readDword(DIF_MISC_CTRL, &misc_ctrl);
//misc_ctrl &= 0xC7FFFFFF;
//misc_ctrl |= 0x20000000;
misc_ctrl &= 0x00FFFFFF;
misc_ctrl |= 0x22000001;
_p_registers->writeDword(DIF_MISC_CTRL, misc_ctrl);
pauseThread(10);
_p_registers->readDword(DIF_MISC_CTRL, &misc_ctrl);
//misc_ctrl &= 0xC7FFFFFF;
//misc_ctrl |= 0x28000000;
misc_ctrl &= 0x00FFFFFF;
misc_ctrl |= 0x32000001;
_p_registers->writeDword(DIF_MISC_CTRL, misc_ctrl);
_p_registers->readDword(DIF_MISC_CTRL, &misc_ctrl);
//misc_ctrl &= 0xC7FFFFFF;
//misc_ctrl |= 0x28000000;
misc_ctrl &= 0x00FFFFFF;
misc_ctrl |= 0x3a000001;
_p_registers->writeDword(DIF_MISC_CTRL, misc_ctrl);
}
VOID DirectIF::ResetAgc()
{
DWORD misc_ctrl = 0;
DisableAgc();
pauseThread(2);
//turn back on the rf agc first
EnableAgc();
pauseThread(2);
}
VOID DirectIF::GetAgcAlgorithmEnableState(BOOL* p_enabled)
{
*p_enabled = _enableAGCalgorithm;
}
//
// VOID preChannelChange()
//
// Do any pre-channel change work here
//
VOID DirectIF::preChannelChange()
{
DWORD dwval;
if (_p_registers)
{
// Set the RF and IF k_agc values to 3
_p_registers->readDword(DIF_AGC_IF_REF, &dwval);
dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
dwval |= 0x33000000;
_p_registers->writeDword(DIF_AGC_IF_REF, dwval);
}
}
//
// VOID postChannelChange()
//
// Do any post-channel change work here
//
VOID DirectIF::postChannelChange()
{
DWORD dwval;
if (_p_registers)
{
// Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for SECAM
_p_registers->readDword(DIF_AGC_IF_REF, &dwval);
dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
switch (_standard)
{
case KS_AnalogVideo_SECAM_B:
case KS_AnalogVideo_SECAM_D:
case KS_AnalogVideo_SECAM_L:
dwval |= 0x88000000;
break;
default:
dwval |= 0x44000000;
break;
}
_p_registers->writeDword(DIF_AGC_IF_REF, dwval);
}
}
// Function name : DirectIF::ConfigureC2HHforLowIF
// Description :
// Return type : VOID
VOID DirectIF::ConfigureC2HHforLowIF(ULONG mode)
{
if(mode == KSPROPERTY_TUNER_MODE_FM_RADIO)
{
// C2HH
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1); // lo if big signal
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 23, 24, 0x1); // FUNC_MODE = DIF
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xFF); // IF_MODE
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1); // no inv
}
else
{
switch(_standard)
{
case KS_AnalogVideo_NTSC_M: // 75 IRE Setup
case KS_AnalogVideo_NTSC_M_J: // Japan, 0 IRE Setup
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1); // lo if big signal
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 23, 24, 0x1); // FUNC_MODE = DIF
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xb); // IF_MODE
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1); // no inv
_p_registers->RegMaskWrite(32, AUD_IO_CTRL, 0, 31, 0x00000003); // 0x124, AUD_CHAN1_SRC = 0x3
break;
case KS_AnalogVideo_PAL_B:
case KS_AnalogVideo_PAL_G:
// C2HH setup
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1); // lo if big signal
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 23, 24, 0x1); // FUNC_MODE = DIF
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xE); // IF_MODE
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1); // no inv
break;
case KS_AnalogVideo_PAL_D:
case KS_AnalogVideo_PAL_I:
case KS_AnalogVideo_SECAM_L:
case KS_AnalogVideo_SECAM_L1:
// C2HH setup
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1); // lo if big signal
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 23, 24, 0x1); // FUNC_MODE = DIF
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xF); // IF_MODE
_p_registers->RegMaskWrite(32, AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1); // no inv
case KS_AnalogVideo_PAL_M:
case KS_AnalogVideo_PAL_N:
case KS_AnalogVideo_PAL_N_COMBO:
break;
case DIF_USE_BASEBAND:
default:
//do nothing to config C2HH for baseband
break;
}
}
}
//
// VOID setDIFbandpass(DWORD if_freq, BOOL spectral_invert)
//
// Sets the DIF bandpass filter based on IF frequency
// Rounds to nearest 100 KHz value
// Valid if_freq is from 3 to 16 MHz
//
VOID DirectIF::setDIFbandpass(DWORD if_freq, BOOL spectral_invert, ULONG mode)
{
LONGLONG pll_freq;
unsigned long pll_freq_word;
DbgLog(("DirectIF::setDIFbandpass : Will set for IF_Freq = %ld, spectral_invert = %d\n", if_freq, spectral_invert));
// if_freq is the value being used by Sidewinder for its mid-band IF frequency
// Need to offset to video carrier for DIF BPF and then 400 KHz additional for adjacent guardband
setStandard(_standard, mode);
if (mode == KSPROPERTY_TUNER_MODE_FM_RADIO)
{
pll_freq_word = 0x905A1CAC;
_p_registers->writeDword(DIF_PLL_FREQ_WORD, pll_freq_word);
}
else //KSPROPERTY_TUNER_MODE_TV
{
// Calculate the PLL frequency word based on the adjusted if_freq
pll_freq = ((LONGLONG) if_freq * 268435456)/50000000;
pll_freq_word = (unsigned long) pll_freq;
_p_registers->writeDword(DIF_PLL_FREQ_WORD, pll_freq_word);
if (spectral_invert)
{
if_freq -= 400000;
// Enable Spectral Invert
_p_registers->readModifyWriteDword(DIF_MISC_CTRL, FLD_DIF_SPEC_INV, _p_registers->Set_Field(FLD_DIF_SPEC_INV, 0x1) );
}
else
{
if_freq += 400000;
// Disable Spectral Invert
_p_registers->readModifyWriteDword(DIF_MISC_CTRL, FLD_DIF_SPEC_INV, _p_registers->Set_Field(FLD_DIF_SPEC_INV, 0x0) );
}
if_freq = (if_freq/100000)*100000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -