⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tuner_pal.c

📁 mstar 776 开发的车载dvd
💻 C
📖 第 1 页 / 共 2 页
字号:

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 + -