📄 tuner.cpp
字号:
// This provides the freq at the center of the 6 MHz band. It seems that the
// Microsoft table provides the freq at the left edge of the band. For
// the Philips tuner, you need to use the center freq. So, I imagine that
// you'll have to add a 1.75 MHz offset to all channels.
//
// This is equivalent to (Frf + 3 e6) + Fif / 8 * 7.8125 KHz
//
DbgLogInfo(("Will set actual freq to (%d), freq = %d + 1.75 MHz\n", ulFreq + 1750000, ulFreq));
llTemp = ( (llTemp + 1750000) + pTunerDataExt->ulIntermediateFrequency );
llTemp /= 62500; // (8 * 7.8125KHz)
WORD wTemp = (WORD)( llTemp & 0x000000000000FFFF );
aucData[ 0 ] = HIBYTE( wTemp );
aucData[ 1 ] = LOBYTE( wTemp );
aucData[ 2 ] = HIBYTE( wControl ); // Charge pump high
aucData[ 3 ] = LOBYTE( wControl );
DbgLogInfo(( "freq 0x%08X (%lu)\n", ulFreq, ulFreq ));
DbgLogInfo(( "Intermediate freq %lu\n", pTunerDataExt->ulIntermediateFrequency ));
DbgLogInfo(( "i2c address = 0x%02X\n", pTunerDataExt->ucTunerI2CAddress));
DbgLogInfo(( "i2c divider bytes = 0x%02X 0x%02X\n", aucData[ 0 ], aucData[ 1 ] ));
DbgLogInfo(( "i2c control bytes = 0x%02X 0x%02X\n", aucData[ 2 ], aucData[ 3 ] ));
if(!pTunerDataExt->i2c_interface.write(pTunerDataExt->ucTunerI2CAddress, aucData, sizeof(aucData)))
{
DbgLogError(( "I2C write failed setting Philips 1236D tuner freq.\n" ));
return ( FALSE );
}
WaitCount = 200; // 200 ms timeout
while (!bLocked && WaitCount--)
{
PauseExecution(1);
if(pTunerDataExt->i2c_interface.read(pTunerDataExt->ucTunerI2CAddress, &ucStatus))
{
//DbgLog(( "I2CRead() success\n" ));
}
else
{
DbgLogWarn(( "I2CRead() failed\n" ));
}
if( ucStatus & 0x40 ) // bit 6 - PLL locked indicator
{
DbgLogInfo(("tuner is locked\n"));
bLocked = TRUE;
break;
}
}
if ( pTunerDataExt->ulTunerMode == KSPROPERTY_TUNER_MODE_ATSC &&
pTunerDataExt->bNxtWaveSetup )
{
// No locked status for ATSC
DbgLogInfo(("Start NxtWave tracking after channel change\n"));
DemodNxtWaveThreadInit( pTunerDataExt ); // re-start tracking
}
// If tuner locked, set the charge pump low
if ( bLocked )
{
wTemp = (WORD)( llTemp & 0x000000000000FFFF );
aucData[ 0 ] = HIBYTE( wTemp );
aucData[ 1 ] = LOBYTE( wTemp );
aucData[ 2 ] = (HIBYTE( wControl )) & 0xBF; // Charge pump low
aucData[ 3 ] = LOBYTE( wControl );
if (!pTunerDataExt->i2c_interface.write(pTunerDataExt->ucTunerI2CAddress, aucData, sizeof(aucData)))
{
DbgLogError(( "I2C write failed setting Philips 1236D tuner freq.\n" ));
return ( FALSE );
}
}
return ( TRUE );
}
/*++ ********************************************************************\
*
* Function:
*
* BOOL TunerSet4In1TunerAudioMode( PHW_STREAM_REQUEST_BLOCK pSrb )
*
* Purpose:
*
* Set the Tuner 4 In 1 tuner bytes for switching between
* FM radio and TV audio standards.
*
* Return:
*
* TRUE - I2C was successful
* FALSE - I2C failed
*
* History:
*
*
\******************************************************************** --*/
BOOL TunerSet4In1TunerAudioMode( PTUNER_DATA_EXTENSION pTunerDataExt, BOOLEAN turn_on_fm_sensitivity )
{
BYTE aucData[ 6 ];
int i;
const BYTE WriteSize = 2;
const BYTE I2CAddrAudio = 0x86; // I2C addr for programming audio modes
DbgLogInfo(("TunerSet4In1AudioMode\n"));
aucData[ 0 ] = 0; // Switch register subaddress
aucData[ 2 ] = 1; // Adjust register subaddress
aucData[ 4 ] = 2; // Data register subaddress
if ( pTunerDataExt->ulTunerMode == KSPROPERTY_TUNER_MODE_FM_RADIO )
{
// FM Audio
switch ( pTunerDataExt->uiTunerType )
{
case TEMIC_4_IN_1:
aucData[ 1 ] = kTemic4049_FM_Switch; // Switch register value
aucData[ 3 ] = kTemic4049_FM_Adjust; // Adjust register value
aucData[ 5 ] = kTemic4049_FM_Data; // Data register value
break;
case PHILIPS_FM1236_MK3:
case PHILIPS_FM1286_MK3:
aucData[ 1 ] = kPhilipsFM1236_FM_Stereo_Switch; // Switch register value
aucData[ 3 ] = kPhilipsFM1236_FM_Stereo_Adjust; // Adjust register value
aucData[ 5 ] = kPhilipsFM1236_FM_Stereo_Data; // Data register value
break;
case PHILIPS_FM1216_MK3:
aucData[ 1 ] = kPhilips1216_FM_Stereo_Switch; // Switch register value
aucData[ 3 ] = kPhilips1216_FM_Stereo_Adjust; // Adjust register value
aucData[ 5 ] = kPhilips1216_FM_Stereo_Data; // Data register value
break;
case THOMSON_DTT761x:
aucData[ 1 ] = kThomson761x_FM_Switch; // Switch register value
aucData[ 3 ] = kThomson761x_FM_Adjust; // Adjust register value
aucData[ 5 ] = kThomson761x_FM_Data; // Data register value
break;
case PHILIPS_FMD1216_ME:
aucData[ 1 ] = kPhilipsFMD1216_FM_Stereo_Switch; // Switch register value
aucData[ 3 ] = kPhilipsFMD1216_FM_Stereo_Adjust; // Adjust register value
aucData[ 5 ] = kPhilipsFMD1216_FM_Stereo_Data; // Data register value
break;
default:
DbgLogInfo(("4 In 1 TunerType = %d doesn't support FM radio\n", pTunerDataExt->uiTunerType));
break;
}
if(turn_on_fm_sensitivity)
{
aucData[1] |= 0x40;
}
// write out data register bytes, tuner can handle only two bytes
// in an i2c transaction.
for ( i = 0; i < sizeof( aucData ); )
{
if(!pTunerDataExt->i2c_interface.write(I2CAddrAudio, &aucData[i], WriteSize))
{
DbgLogError(( "I2C write failed setting data byte\n" ));
return ( FALSE );
}
DbgLogInfo(("%x %x\n", aucData[i], aucData[i+1]));
i += WriteSize;
}
}
else
{
// TV audio
// found on Win2K video standard is KS_AnalogVideo_None
if ( pTunerDataExt->ulStandard == KS_AnalogVideo_None )
{
DbgLogInfo(("video standard defined as None!, getting standard set in video decoder\n"));
pTunerDataExt->ulStandard = SendVideoStandardCommand(pTunerDataExt);
}
switch ( pTunerDataExt->ulStandard )
{
case KS_AnalogVideo_NTSC_M:
case KS_AnalogVideo_NTSC_M_J:
DbgLogInfo(("Video Standard = NTSC M\n"));
switch ( pTunerDataExt->uiTunerType )
{
case PHILIPS_FM1236_MK3:
case PHILIPS_FQ1236_MK3:
aucData[ 1 ] = kPhilipsFM1236_NTSC_M_Switch; // Philips switch register value
aucData[ 3 ] = kPhilipsFM1236_NTSC_M_Adjust; // Philips adjust register value
aucData[ 5 ] = kPhilipsFM1236_NTSC_M_Data; // Philips data register value
break;
case PHILIPS_FI1236_MK3:
aucData[ 1 ] = kPhilipsFI1236_NTSC_M_Switch; // Philips switch register value
aucData[ 3 ] = kPhilipsFI1236_NTSC_M_Adjust; // Philips adjust register value
aucData[ 5 ] = kPhilipsFI1236_NTSC_M_Data; // Philips data register value
break;
case PHILIPS_FM1286_MK3:
aucData[ 1 ] = kPhilipsFM1286_NTSC_M_Switch; // Philips switch register value
aucData[ 3 ] = kPhilipsFM1286_NTSC_M_Adjust; // Philips adjust register value
aucData[ 5 ] = kPhilipsFM1286_NTSC_M_Data; // Philips data register value
break;
case THOMSON_DTT761x:
aucData[ 1 ] = kThomson761x_NTSC_Switch; // Thomson switch register value
aucData[ 3 ] = kThomson761x_NTSC_Adjust; // Thomson adjust register value
aucData[ 5 ] = kThomson761x_NTSC_Data; // Thomson data register value
break;
default:
DbgLogInfo(("4 In 1 TunerType = %d doesn't support NTSC\n", pTunerDataExt->uiTunerType));
break;
}
// write out data register bytes, tuner can handle only two bytes
// in an i2c transaction.
for ( i = 0; i < sizeof( aucData ); )
{
if(!pTunerDataExt->i2c_interface.write(I2CAddrAudio, &aucData[i], WriteSize))
{
DbgLogError(( "I2C write failed setting data byte\n" ));
return ( FALSE );
}
DbgLogInfo(("%x %x\n", aucData[i], aucData[i+1]));
i += WriteSize;
}
break;
case KS_AnalogVideo_PAL_B:
case KS_AnalogVideo_PAL_G:
DbgLogInfo(("Video Standard = PAL B/G\n"));
switch ( pTunerDataExt->uiTunerType )
{
case TEMIC_4_IN_1:
aucData[ 1 ] = kTemic4049_PAL_Switch; // Temic switch register value
aucData[ 3 ] = kTemic4049_PAL_Adjust; // Temic adjust register value
aucData[ 5 ] = kTemic4049_PALBG_Data; // Temic data register value
break;
case PHILIPS_FM1216_MK3:
case PHILIPS_FQ1216_MK3:
aucData[ 1 ] = kPhilips1216_PAL_BG_Switch; // Philips switch register value
aucData[ 3 ] = kPhilips1216_PAL_BG_Adjust; // Philips adjust register value
aucData[ 5 ] = kPhilips1216_PAL_BG_Data; // Philips data register value
break;
case PHILIPS_FMD1216_ME:
aucData[ 1 ] = kPhilipsFMD1216_PAL_BG_Switch; // Philips switch register value
aucData[ 3 ] = kPhilipsFMD1216_PAL_BG_Adjust; // Philips adjust register value
aucData[ 5 ] = kPhilipsFMD1216_PAL_BG_Data; // Philips data register value
break;
default:
DbgLogInfo(("4 In 1 TunerType = %d doesn't support PAL-B/G\n", pTunerDataExt->uiTunerType));
break;
}
// write out data register bytes, tuner can handle only two
// in an i2c transaction.
for ( i = 0; i < sizeof( aucData ); )
{
if (!pTunerDataExt->i2c_interface.write(I2CAddrAudio, &aucData[i], WriteSize))
{
DbgLogError(( "I2C write failed setting data byte\n" ));
return ( FALSE );
}
DbgLogInfo(("%x %x\n", aucData[i], aucData[i+1]));
i += WriteSize;
}
break;
case KS_AnalogVideo_PAL_D:
// case KS_AnalogVideo_PAL_K:
DbgLogInfo(("Video Standard = PAL D/K\n"));
switch ( pTunerDataExt->uiTunerType )
{
case TEMIC_4_IN_1:
aucData[ 1 ] = kTemic4049_PAL_Switch; // Temic switch register value
aucData[ 3 ] = kTemic4049_PAL_Adjust; // Temic adjust register value
aucData[ 5 ] = kTemic4049_PALDK_Data; // Temic data register value
break;
case PHILIPS_FM1216_MK3:
case PHILIPS_FQ1216_MK3:
aucData[ 1 ] = kPhilips1216_PAL_DK_Switch; // Philips switch register value
aucData[ 3 ] = kPhilips1216_PAL_DK_Adjust; // Philips adjust register value
aucData[ 5 ] = kPhilips1216_PAL_DK_Data; // Philips data register value
break;
case PHILIPS_FMD1216_ME:
aucData[ 1 ] = kPhilipsFMD1216_PAL_DK_Switch; // Philips switch register value
aucData[ 3 ] = kPhilipsFMD1216_PAL_DK_Adjust; // Philips adjust register value
aucData[ 5 ] = kPhilipsFMD1216_PAL_DK_Data; // Philips data register value
break;
default:
DbgLogInfo(("4 In 1 TunerType = %d doesn't support PAL-D/K\n", pTunerDataExt->uiTunerType));
break;
}
// write out data register bytes, tuner can handle only two bytes
// in an i2c transaction.
for ( i = 0; i < sizeof( aucData ); )
{
if (!pTunerDataExt->i2c_interface.write(I2CAddrAudio, &aucData[i], WriteSize))
{
DbgLogError(( "I2C write failed setting data byte\n" ));
return ( FALSE );
}
DbgLogInfo(("%x %x\n", aucData[i], aucData[i+1]));
i += WriteSize;
}
break;
case KS_AnalogVideo_PAL_I:
DbgLogInfo(("Video Standard = PAL I\n"));
switch ( pTunerDataExt->uiTunerType )
{
case TEMIC_4_IN_1:
aucData[ 1 ] = kTemic4049_PAL_Switch; // Temic switch register value
aucData[ 3 ] = kTemic4049_PAL_Adjust; // Temic adjust register value
aucData[ 5 ] = kTemic4049_PALI_Data; // Temic data register value
break;
case PHILIPS_FM1216_MK3:
case PHILIPS_FQ1216_MK3:
aucData[ 1 ] = kPhilips1216_PAL_I_Switch; // Philips switch register value
aucData[ 3 ] = kPhilips1216_PAL_I_Adjust; // Philips adjust register value
aucData[ 5 ] = kPhilips1216_PAL_I_Data; // Philips data register value
break;
case PHILIPS_FMD1216_ME:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -