📄 tuner_pal.c
字号:
U8 devTunerSetChannel( EnuTunerSoundSystem ucSoundSystem, U16 wFreq )
{
// Dummy code for avoid compile warning
ucSoundSystem++;
return (devTunerSetFreq( wFreq ));
}
void devTunerInitialize(void)
{
//devTunerSetSubSys(TUNER_SOUND_BG);
g_TunerPara.ProgDivide = 0x00;
g_TunerPara.ControlInfo1 = 0xCE;
g_TunerPara.ControlInfo2 = 0X10;
devTunerWrite( &g_TunerPara );
devTunerSetSubSys(TUNER_SOUND_BG);
}
U8 ucStatus; // tuner status
U8 devTunerGetStatus(U8 ucLoopCount)
{
U8 ucTmp = 0;
do // loop to detect
{
// read tuner status
MDrv_IIC_ReadBytes(TN_IF_I2C_ADDR, 0, (U8*)NULL, 1, &ucStatus);
//if (ucStatus & TN_READ_AFCWIN) // check inside AFC Window
if( ucStatus == ucTmp )
break;
else
ucTmp = ucStatus;
if (ucLoopCount-- == 0) break;
MDrv_Timer_Delayms(5);
}while(1);
return ucStatus; // return status
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: devTunerWrite
//
// <Description>: Set tuner parameter.
//
// <Returns> : tuner status
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// pProgParam - In - program parameter
///////////////////////////////////////////////////////////////////////////////
U8 devTunerWrite(TunerProgramType *pProgParam)
{
U8 ucStatus,ucLoop=20;
BOOLEAN temp;
ZL10353_RepeatControl(ENABLE);
MDrv_Timer_Delayms(5);
temp=MDrv_IIC_WriteBytes(TN_PROG_I2C_ADDR, 0, NULL, sizeof(TunerProgramType), (U8 *)pProgParam);
MDrv_Timer_Delayms(150);
while(--ucLoop)
{
ucStatus = devTunerGetStatus(5);
if(ucStatus&_BIT6) //check PLL is locked
{
break;
}
MDrv_Timer_Delayms(5);
}
ZL10353_RepeatControl(DISABLE);
return ucStatus; // tuner status
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: devTunerFineTuneFreq
//
// <Description>: Fine tune tuner frequency.
//
// <Returns> : If fine tune successful
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// wOriFreq - In - original freq
// pwResultFreq - Out - result freq
///////////////////////////////////////////////////////////////////////////////
BOOLEAN devTunerFineTuneFreq( U16 wOriFreq, U16* pwResultFreq )
{
U8 ucStatus;
U8 ucAFC;
char cStep;
U8 ucMaxLoopCount;//64; // Protection: don't let program die
U8 u8BestAFC;
U16 u16BestFreq;
u16BestFreq = 0;
u8BestAFC = 0;
ucMaxLoopCount = 8;
*pwResultFreq = wOriFreq;
DBG_TN(( "%d ==> ", wOriFreq/TN_FREQ_SS_INVERSE ));
ucStatus = devTunerSetFreq( wOriFreq );
if( 0 == (ucStatus & TN_READ_AFCWIN) ) // No signal
{
MDrv_Timer_Delayms(50);
ucStatus = devTunerGetStatus(5);
if( 0 == (ucStatus & TN_READ_AFCWIN) ) // No signal
return FALSE;
}
ucAFC = (ucStatus&TN_READ_AFC)>>1;
DBG_TN(("\r\nAFC = 0x%bx",ucAFC));
if( ucAFC < 2 || ucAFC > 13 ) // 0,1,14,15 ==> Freq is good enough
{
DBG_TN(( "%d", (*pwResultFreq)/TN_FREQ_SS_INVERSE));
//DBG_TN(",%X", TN_N(*pwResultFreq));
return TRUE; // Good freq has found
}
// Setup the direction of search
if( ucAFC < 8 ) // 2,3,4,5,6,7
{
cStep = 1;
}
else // 8,9,10,11,12,13
{
cStep = -1;
}
while( ucMaxLoopCount-- )
{
wOriFreq += cStep; // +/- 0.625 MHz
// Save the last freq
*pwResultFreq = wOriFreq;
ucStatus = devTunerSetFreq( wOriFreq );
DBG_TN(("\r\nFinetune %f Mhz",(float)wOriFreq/16));
DBG_TN(("\r\nAFC 0x%bx",(ucStatus&TN_READ_AFC)>>1));
if( 0 == (ucStatus & TN_READ_AFCWIN) ) // No signal
{
//DBG_TN(( "Outside AFC:%dMHz, %X", wOriFreq/TN_FREQ_SS_INVERSE, TN_N(wOriFreq)));
MDrv_Timer_Delayms(100);
ucStatus = devTunerGetStatus(5);
if( 0 == (ucStatus & TN_READ_AFCWIN) ) // No signal
return FALSE;
}
ucAFC = (ucStatus&TN_READ_AFC)>>1;
if( ucAFC < 2 || ucAFC > 13 ) // 0,1,14,15 ==> Freq is good enough
{
if(u16BestFreq == 0)
{
u8BestAFC = ucAFC;
u16BestFreq = wOriFreq;
continue;
}
// Check if search range is over
else
{
if(abs(ucAFC-8) > abs(u8BestAFC-8))
{
u8BestAFC = ucAFC;
u16BestFreq = wOriFreq;
}
//else // if( -1 == cStep ) // 8,9,10,11,12,13
continue;
}
return TRUE; // Good freq has found
}
}
if(u16BestFreq != 0)
{
*pwResultFreq = u16BestFreq;
return TRUE;
}
DBG_TN(("\r\nLast AFC = 0x%bx",ucAFC));
DBG_TN((" \nNear but not good enough" ));
return FALSE;
}
#else //Digital IF Tuner & Analog IF MIXER & Analog IF demodulator NOT included in Single CAN module
code U8 tIFBCETable[TUNER_SOUND_NUMS][3] =
{
#if ((FRONTEND_IF_DEMODE_TYPE==PHILIPS_TDA9886))
// B C E
{ 0x16, 0x70, 0x49 }, // B/G
{ 0x16, 0x70, 0x4A }, // I
{ 0x16, 0x70, 0x4B }, // D/K
{ 0x06, 0x70, 0x4B }, // L
{ 0x86, 0x70, 0x53 }, // L'
#endif
};
//daniel_to_do
//#define vdChkStatusLoop(x,y) VD_HSYNC_LOCKED
void devTunerSetIF( EnuTunerSoundSystem ucSoundSystem )
{
U8 i, ucTemp;
ucTemp = (ucSoundSystem==TUNER_SOUND_AUTO)?0:ucSoundSystem-1;
if( ucSoundSystem >= TUNER_SOUND_NUMS )
ucSoundSystem = 0;
for( i = 0; i < 3; ++ i )
MDrv_IIC_WriteByte(TN_IF_I2C_ADDR, i, tIFBCETable[ucTemp][i]);
}
void devTunerSetSubSys( EnuTunerSoundSystem ucSoundSystem )
{
devTunerSetIF( ucSoundSystem );
if( TUNER_SOUND_LL == ucSoundSystem )
g_TuneFreqIF = 33.95 * 16;
else
g_TuneFreqIF = 38.9 * 16;
}
// For NTSC test
#define TN_FREQ_IF 45.75 // MHz
//#define TN_N(Frf) ((UINT)(((Frf + TN_FREQ_IF) * 1000) / TN_FREQ_SS))
#define TN_N(Frf) ((UINT)(((Frf + TN_FREQ_IF*16)/16 * 1000) / TN_FREQ_SS))
// subSys: M B/G I D/K L/L`
// wFreq: wFreq*16 ==> xxxx MHz
// Return Tuner status
U8 devTunerSetFreq( U16 wFreq )
{
#if (PATCH_PAL_VTOTAL624SHAKE)
U8 u8Bank;
u8Bank = XBYTE[BK_SELECT_00]; // store bank
XBYTE[BK_SELECT_00] = REG_BANK_COMB;
MDrv_WriteRegBit( BK_COMB_50, ENABLE,_BIT0);//enable H/W auto Htotal
XBYTE[BK_SELECT_00] = u8Bank; // recovery bank
#endif
// Pal tuner:
g_TunerPara.ProgDivide = wFreq + g_TuneFreqIF;
g_TunerPara.ControlInfo1 = 0x80 | TN_RSA_RSB ;
if( wFreq < (160*16) ) // low bank
g_TunerPara.ControlInfo2 = TN_LOW_BAND;
else if( wFreq < (442.00 * 16)) // middle band
g_TunerPara.ControlInfo2 = TN_MID_BAND;
else
g_TunerPara.ControlInfo2 = TN_HIGH_BAND;
//////////////////////////////////////////////////////////////
// Test: use NTSC tuner
// g_TunerPara.ProgDivide = TN_N(wFreq);
//DBG_TN(("freq=%d,",wFreq/16));
//DBG_TN(("divider=%X\r\n",g_TunerPara.ProgDivide));
return devTunerWrite( &g_TunerPara );
}
U8 devTunerSetChannel( EnuTunerSoundSystem ucSoundSystem, U16 wFreq )
{
devTunerSetSubSys( ucSoundSystem );
return (devTunerSetFreq( wFreq ));
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: tnInitializeChip
//
// <Description>: Initialize tuner chip.
///////////////////////////////////////////////////////////////////////////////
void devTunerInitialize(void)
{
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: devTunerGetStatus
//
// <Description>: Get tuner status.
//
// <Returns> : tuner status
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// ucLoopCount - In - loop counter
///////////////////////////////////////////////////////////////////////////////
U8 devTunerGetStatus(U8 ucLoopCount)
{
U8 ucTmp = 0;
U8 ucStatus; // tuner status
do // loop to detect
{
// read tuner status
MDrv_IIC_ReadBytes(TN_IF_I2C_ADDR, 0, (U8*)NULL, 1, &ucStatus);
//if (ucStatus & TN_READ_AFCWIN) // check inside AFC Window
if( ucStatus == ucTmp )
break;
else
ucTmp = ucStatus;
if (ucLoopCount-- == 0) break;
MDrv_Timer_Delayms(5);
}while(1);
return ucStatus; // return status
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: devTunerWrite
//
// <Description>: Set tuner parameter.
//
// <Returns> : tuner status
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// pProgParam - In - program parameter
///////////////////////////////////////////////////////////////////////////////
U8 devTunerWrite(TunerProgramType *pProgParam)
{
//i2cBurstWriteBytes(TN_PROG_I2C_ADDR, HIU8(pProgParam->ProgDivide),
// ((U8 *)pProgParam) + 1, sizeof(TunerProgramType) - 1);
U8 ucStatus,ucLoop=20;
MDrv_IIC_WriteBytes(TN_PROG_I2C_ADDR, 0, NULL, sizeof(TunerProgramType), (U8 *)pProgParam);
MDrv_Timer_Delayms(150);
while(--ucLoop)
{
ucStatus = devTunerGetStatus(5);
if(ucStatus&_BIT6) //check PLL is locked
break;
MDrv_Timer_Delayms(5);
}
return ucStatus; // tuner status
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: devTunerFineTuneFreq
//
// <Description>: Fine tune tuner frequency.
//
// <Returns> : If fine tune successful
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// wOriFreq - In - original freq
// pwResultFreq - Out - result freq
///////////////////////////////////////////////////////////////////////////////
BOOLEAN devTunerFineTuneFreq( U16 wOriFreq, U16* pwResultFreq )
{
U8 ucStatus;
U8 ucAFC;
char cStep;
U8 ucMaxLoopCount;//64; // Protection: don't let program die
U8 u8BestAFC;
U16 u16BestFreq;
u16BestFreq = 0;
u8BestAFC = 0;
ucMaxLoopCount = 8;
*pwResultFreq = wOriFreq;
DBG_TN(( "%d ==> ", wOriFreq/TN_FREQ_SS_INVERSE ));
ucStatus = devTunerSetFreq( wOriFreq );
if( 0 == (ucStatus & TN_READ_AFCWIN) ) // No signal
{
MDrv_Timer_Delayms(50);
ucStatus = devTunerGetStatus(5);
if( 0 == (ucStatus & TN_READ_AFCWIN) ) // No signal
return FALSE;
}
ucAFC = (ucStatus&TN_READ_AFC)>>1;
DBG_TN(("\r\nAFC = 0x%bx",ucAFC));
if( ucAFC < 2 || ucAFC > 13 ) // 0,1,14,15 ==> Freq is good enough
{
DBG_TN(( "%d", (*pwResultFreq)/TN_FREQ_SS_INVERSE));
DBG_TN((",%X", TN_N(*pwResultFreq));
return TRUE; // Good freq has found
}
// Setup the direction of search
if( ucAFC < 8 ) // 2,3,4,5,6,7
{
cStep = 1;
}
else // 8,9,10,11,12,13
{
cStep = -1;
}
while( ucMaxLoopCount-- )
{
wOriFreq += cStep; // +/- 0.625 MHz
// Save the last freq
*pwResultFreq = wOriFreq;
ucStatus = devTunerSetFreq( wOriFreq );
DBG_TN(("\r\nFinetune %f Mhz",(float)wOriFreq/16));
DBG_TN(("\r\nAFC 0x%bx",(ucStatus&TN_READ_AFC)>>1));
if( 0 == (ucStatus & TN_READ_AFCWIN) ) // No signal
{
DBG_TN(( "Outside AFC:%dMHz, %X", wOriFreq/TN_FREQ_SS_INVERSE, TN_N(wOriFreq)));
MDrv_Timer_Delayms(100);
ucStatus = devTunerGetStatus(5);
if( 0 == (ucStatus & TN_READ_AFCWIN) ) // No signal
return FALSE;
}
ucAFC = (ucStatus&TN_READ_AFC)>>1;
if( ucAFC < 2 || ucAFC > 13 ) // 0,1,14,15 ==> Freq is good enough
{
if(u16BestFreq == 0)
{
u8BestAFC = ucAFC;
u16BestFreq = wOriFreq;
continue;
}
// Check if search range is over
else
{
if(abs(ucAFC-8) > abs(u8BestAFC-8))
{
u8BestAFC = ucAFC;
u16BestFreq = wOriFreq;
}
continue;
}
return TRUE; // Good freq has found
}
}
if(u16BestFreq != 0)
{
printf("\r\nBest freq = %f",(float)u16BestFreq/16);
*pwResultFreq = u16BestFreq;
return TRUE;
}
DBG_TN(("\r\nLast AFC = 0x%bx",ucAFC));
DBG_TN((" \nNear but not good enough" ));
return FALSE;
}
#endif
WORD devTunerScanFreq( WORD wFreq )
{
U8 ucStatus;
WORD wResultFreq;
ucStatus = devTunerSetFreq( wFreq );
#if (FRONTEND_TUNER_TYPE==PHILIPS_FQD1216_TUNER)
devTunerSetSubSys(TUNER_SOUND_AUTO);
#endif
//printf("\r\nSetFreq = %f",(float)wFreq/16);
DBG_TN(("\r\nStatus = 0x%bx",ucStatus));
if( (ucStatus & (TN_READ_AFCWIN |TN_READ_VIFL)) == (TN_READ_AFCWIN |TN_READ_VIFL) ) // Near the signal
{
DBG_TN(("\r\nStart Finetune"));
// Find the better freq
if( devTunerFineTuneFreq( wFreq, &wResultFreq ) )
{
DBG_TN(("\r\nFinetune done"));
MDrv_Timer_Delayms(200);
if(msAPI_VD_ChkStatusLoop() & VD_HSYNC_LOCKED)
{
//printf("\r\n jason Tuner Video Auto-Scan done %fMhz",(float)(wResultFreq)/16);
PAL_DBG_MSG(printf("\r\nTuner Video Auto-Scan done %fMhz",(float)(wResultFreq)/16));
return wResultFreq;
}
PAL_DBG_MSG(printf("\r\nVD Status is 0x%x",msAPI_VD_GetStatus()));
}
else
DBG_TN(("\r\nFinetune fail"));
}
return 0; // No channel found!!
}
#undef DBG_TN
#undef TUNER_PAL_C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -