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

📄 tuner_pal.c

📁 mstar 776 开发的车载dvd
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 Copyright (c) 2004 MStar Semiconductor, Inc.
 All rights reserved.

 [Module Name]: DevTuner.c
 [Date]:        30-Mar-2004
 [Comment]:
   TV tuner subroutines.
 [Reversion History]:
*******************************************************************************/

#define TUNER_PAL_C

// System

// Common
#include <stdio.h>
#include <math.h>
#include "board.h"


#include "DataType.h"
#include "Drviic.h"
#include "drvTimer.h"
#include "drvVD.h"
#include "msAPI_VD.h"

#include "Tuner_pal.h"
#include "ZL10353.H"

#define DEBUG_PAL_TUNER   0

#if   DEBUG_PAL_TUNER
#define  DBG_TN(x)    printf x
#define PAL_DBG_MSG(x)  x
#else
#define  DBG_TN(x)
#define PAL_DBG_MSG(x)
#endif

TunerProgramType g_TunerPara;
U16 g_TuneFreqIF;

#if (FRONTEND_TUNER_TYPE==FRONTEND_IF_MIXER_TYPE==FRONTEND_IF_DEMODE_TYPE==THOMSON_FE6640_TUNER)

#define SETTING_AT_INITIAL  0

void devTunerSet_COFDM_I2C_BypassTable(BOOLEAN ONOFF)
{
    //#if(FRONTEND_DEMOD_TYPE==ZARLINK_ZL10353_DEMODE)
    #if 1
    if(ONOFF==ENABLE)
    	ZL10353_RepeatControl(ENABLE);
    else
    	ZL10353_RepeatControl(DISABLE);
    #endif
}

void devTunerSetTable(void)
{
    BOOLEAN bResult;

    devTunerSet_COFDM_I2C_BypassTable(ENABLE);

#if (SETTING_AT_INITIAL==1)
    MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x00, 0x0000, 0x8000);
    MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x03, 0x0000, 0x000C);
#endif

    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x1001, 0x0021);
    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x1010, 0x00CA);
    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x1012, 0x0008);
    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x1013, 0x000A);
    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x1016, 0x01C0);

    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x10B0, 0x0001);

    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x100F, 0x05B0);
    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x100F, 0x0580);
    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x100E, 0x0000);
    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x100E, 0x0001);
    bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x10, 0x1017, 0x0022);

    devTunerSet_COFDM_I2C_BypassTable(DISABLE);
}

code U16 tIFBCETable[TUNER_SOUND_NUMS][8][2] =
{
    {   // B/G
        {0x0020, 0x0103},
        {0x1022, 0x013D},
        {0x1002, 0x02BC},
        {0x1073, 0x012E},
        {0x1072, 0x00C5},
        {0x1071, 0x0197},
        {0x1070, 0x000F},
        {0xFFFF, 0xFFFF},
    },
    {   // I
        {0x0020, 0x0103},
        {0x1022, 0x0134},
        {0x1002, 0x0314},
        {0x1073, 0x0192},
        {0x1072, 0x0028},
        {0x1071, 0x01F6},
        {0x1070, 0x0007},
        {0xFFFF, 0xFFFF},
    },
    {   // DK
        {0x0020, 0x0004},
        {0x1022, 0x0134},
        {0x1002, 0x02D0},
    #if 1 // China
        {0x1073, 0x0192},
        {0x1072, 0x0028},
        {0x1071, 0x01FA},
        {0x1070, 0x0007},
    #else   // Europe
        {0x1073, 0x018E},
        {0x1072, 0x00B0},
        {0x1071, 0x0198},
        {0x1070, 0x0001},
    #endif
        {0xFFFF, 0xFFFF},
    },
    {   // L
        {0x0020, 0x0009},
        {0x1022, 0x0134},
        {0x1002, 0x028a},
        {0x1073, 0x0192},
        {0x1072, 0x0028},
        {0x1071, 0x01F6},
        {0x1070, 0x0007},
        {0xFFFF, 0xFFFF},
    },
    {   // LL
        {0x0020, 0x0109},
        {0x1022, 0x0198},
        {0x1002, 0x028A},
        {0x1073, 0x0192},
        {0x1072, 0x0028},
        {0x1071, 0x01F6},
        {0x1070, 0x0007},
        {0xFFFF, 0xFFFF},
    },
};


void devTunerSetIF( EnuTunerSoundSystem ucSoundSystem )
{
    BOOLEAN bResult;
    U8 i, ucTemp;

    i = 0;
    ucTemp = (ucSoundSystem==TUNER_SOUND_AUTO)?0:ucSoundSystem-1;

    devTunerSet_COFDM_I2C_BypassTable(ENABLE);

    #if (SETTING_AT_INITIAL==0)
    MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x00, 0x0000, 0x8000);
    MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR, 0x03, 0x0000, 0x000C);
    #endif

    while(tIFBCETable[ucTemp][i][0] != 0xFFFF)
    {
        bResult = MDrv_IIC_WriteGroupBytes(TN_IF_I2C_ADDR,
                                        0x10,
                                        tIFBCETable[ucTemp][i][0],
                                        tIFBCETable[ucTemp][i][1]);
        i++;
    }

    devTunerSet_COFDM_I2C_BypassTable(DISABLE);

    #if (SETTING_AT_INITIAL==0)
    devTunerSetTable();
    #endif
}

void devTunerSetSubSys( EnuTunerSoundSystem ucSoundSystem )
{
    devTunerSetIF( ucSoundSystem );

    if( TUNER_SOUND_LL == ucSoundSystem )
        g_TuneFreqIF = 33.95 * 16;
    else
        g_TuneFreqIF = 38.9 * 16;
}

U16 devTunerGetIF_Quality(U8 u8Times)
{
    U16 u16Data, u16LastData;

    devTunerSet_COFDM_I2C_BypassTable(ENABLE);

    u16LastData = MDrv_IIC_ReadGroupBytes(TN_IF_I2C_ADDR, 0x11, 0x100C);
    do
    {
        MDrv_Timer_Delayms(5);

        u16Data = MDrv_IIC_ReadGroupBytes(TN_IF_I2C_ADDR, 0x11, 0x100C);

        if(abs(u16Data-u16LastData)<0x10)
            break;

        u16LastData = u16Data;

    }while(u8Times--);
    devTunerSet_COFDM_I2C_BypassTable(DISABLE);

    return u16Data;
}

U8 devTunerGetIF_AFC(void)
{
    U16 u16Data;

    devTunerSet_COFDM_I2C_BypassTable(ENABLE);

    u16Data = MDrv_IIC_ReadGroupBytes(TN_IF_I2C_ADDR, 0x11, 0x100B);

    devTunerSet_COFDM_I2C_BypassTable(DISABLE);

    return (U8)((u16Data>>1)&0xFF);
}

U8 devTunerWrite(TunerProgramType *pProgParam)
{
    U8 ucStatus, ucLoop;

    ucLoop = 20;

    devTunerSet_COFDM_I2C_BypassTable(ENABLE);

    MDrv_IIC_WriteBytes(TN_PROG_I2C_ADDR, 0, NULL, sizeof(TunerProgramType), (U8 *)pProgParam);

    MDrv_Timer_Delayms(5);

    pProgParam->ControlInfo1 = (pProgParam->ControlInfo1&0xC7)|0x18;
    pProgParam->ControlInfo2 = 0xA0;
    MDrv_IIC_WriteBytes(TN_PROG_I2C_ADDR, 0, NULL, sizeof(TunerProgramType), (U8 *)pProgParam);

    MDrv_Timer_Delayms(100);

    pProgParam->ControlInfo1 = (pProgParam->ControlInfo1&0xC7)|0x18;
    pProgParam->ControlInfo2 = 0x20;
    MDrv_IIC_WriteBytes(TN_PROG_I2C_ADDR, 0, NULL, sizeof(TunerProgramType), (U8 *)pProgParam);

    devTunerSet_COFDM_I2C_BypassTable(DISABLE);

    MDrv_Timer_Delayms(150);

    while(--ucLoop)
    {
        MDrv_Timer_Delayms(5);
        ucStatus = devTunerGetStatus(5);
        if( (ucStatus&(TN_READ_VIFL|TN_READ_AFCWIN)) == (TN_READ_VIFL|TN_READ_AFCWIN) ) //check PLL is locked
        {
            MDrv_Timer_Delayms(5);
            ucStatus = devTunerGetStatus(5);
            if( (ucStatus&(TN_READ_VIFL|TN_READ_AFCWIN)) == (TN_READ_VIFL|TN_READ_AFCWIN) ) //check PLL is locked
                break;
        }
    }

    PAL_DBG_MSG(printf("\r\nAfter TunerWirte = 0x%bx",ucStatus));

    return ucStatus; // 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;

    if( wFreq < (136.15 * 16) )
        g_TunerPara.ControlInfo1 = 0xF6;
    else if( wFreq < (185.15 * 16) )
        g_TunerPara.ControlInfo1 = 0xFE;
    else if( wFreq < (422.15 * 16) )
        g_TunerPara.ControlInfo1 = 0xF6;
    else if( wFreq < (465.15 * 16) )
        g_TunerPara.ControlInfo1 = 0xFE;
    else if( wFreq < (766.15 * 16) )
        g_TunerPara.ControlInfo1 = 0xF6;
    else if( wFreq < (904.15 * 16) )
        g_TunerPara.ControlInfo1 = 0xFE;
    else
        g_TunerPara.ControlInfo1 = 0xF6;

    if( wFreq < (185.15*16) )  // low bank
        g_TunerPara.ControlInfo2 = 0x11;
    else if( wFreq < (465.15 * 16)) // middle ban
        g_TunerPara.ControlInfo2 = 0x12;
    else
        g_TunerPara.ControlInfo2 = 0x18;

    return(devTunerWrite(&g_TunerPara));
}

U8 devTunerSetChannel( EnuTunerSoundSystem ucSoundSystem, U16 wFreq )
{
    devTunerSetSubSys( ucSoundSystem );
    return (devTunerSetFreq( wFreq ));
}

void devTunerInitialize(void)
{
    #if (SETTING_AT_INITIAL==1)
    devTunerSetTable();
    #endif
}

U8 devTunerGetStatus(U8 ucLoopCount)
{
    U8 ucTmp;
    U8 ucStatus; // tuner status

    ucTmp = 0xFF;

    devTunerSet_COFDM_I2C_BypassTable(ENABLE);

    do // loop to detect
    {
        // read tuner status

        MDrv_IIC_ReadBytes(TN_PROG_I2C_ADDR, 0,  (U8*)NULL,  1,  &ucStatus);

        if( ucStatus == ucTmp )
            break;
        else
            ucTmp = ucStatus;

        if (ucLoopCount-- == 0) break;

        //Delay1ms(1); // delay 1ms
    }while(1);

    if( (ucStatus & 0x70) == 0x70 ) ucStatus = TN_READ_VIFL;
    else ucStatus = 0;

    MDrv_Timer_Delayms(10);

    if( (MDrv_IIC_ReadGroupBytes(TN_IF_I2C_ADDR, 0x11, 0x100B))&0x01 )
        ucStatus |= TN_READ_AFCWIN;

    devTunerSet_COFDM_I2C_BypassTable(DISABLE);

    return ucStatus; // return status
}

#define GOOD_AFC        0x80
#define WEAK_AFC        0x250
#define BAD_AFC        0x700//   0x400


BOOLEAN devTunerFineTuneFreq( U16 wOriFreq, U16* pwResultFreq )
{
    U8 ucStatus;
    U16 u16AFC;
    U16 ucMaxLoopCount;//64; // Protection: don't let program die
    U8 u8AFC, u8AFCRange;
    U8 u8BestAFC;
    U16 u16BestFreq;

    ucMaxLoopCount = 8;
    u8BestAFC = 0xFF;
    u16BestFreq = 0;
    u8AFCRange=0x00;
    *pwResultFreq=0;

    PAL_DBG_MSG(printf( "\r\nStart Finetune %f ==> ", (float)wOriFreq/TN_FREQ_SS_INVERSE ));

    while( ucMaxLoopCount-- )
    {
        //*pwResultFreq=wOriFreq;
        PAL_DBG_MSG(printf("\r\nfront wOriFreq = %f",(float)wOriFreq/16));
        ucStatus = devTunerSetFreq( wOriFreq );
        u8AFCRange = devTunerGetIF_AFC();
        //printf("jason=========wOriFreq=%d++++++++++ucMaxLoopCount=%d---------------u8AFCRange=%bx\n",wOriFreq,ucMaxLoopCount,u8AFCRange);
        u8AFC = (u8AFCRange&0x80)?((~u8AFCRange)+0x01):(u8AFCRange);
        PAL_DBG_MSG(printf("\r\ncAfc= 0x%bx",u8AFCRange));
        u16AFC = devTunerGetIF_Quality(5);

        if(u16AFC > BAD_AFC)
            break;//return FALSE;
        if( u8AFC >=0x32 )//>500K break
        {
            break;
        }
        else if(u8AFC>0x06)
        {
            if(u8AFCRange&0x80)
                wOriFreq += u8AFC/6;
            else
                wOriFreq -= u8AFC/6;
        }
        else if( u8AFC <= 0x06 ) //check AFC is under 60k
        {
            PAL_DBG_MSG(printf("\r\nFinal quality = %x", u16AFC));
            if(u8AFCRange&0x80)
            {
                if(u8AFCRange <= u8BestAFC)
                {
                    u8BestAFC = u8AFCRange;
                u16BestFreq = wOriFreq;
            }
                else
                {
                    break;
                }
                wOriFreq += 1;
        }
            else
        {
                if(u8AFCRange >= u8BestAFC)
            {
                    u8BestAFC =u8AFCRange/* u8AFC*/;
                    u16BestFreq = wOriFreq;
            }
            else
            {
                    break;
                }
                    wOriFreq -= 1;
            }
        }
    }
    if(u16BestFreq)
    {
        *pwResultFreq = u16BestFreq;
        return TRUE;
    }
    return FALSE;
}



#elif (FRONTEND_TUNER_TYPE==PHILIPS_FQD1216_TUNER)


code U8 tIFBCETable[TUNER_SOUND_NUMS][3] =
{
    //  B     C     E
    { 0x56, 0x70, 0x49 }, // B/G
    { 0x56, 0x70, 0x4A }, // I
    { 0x56, 0x70, 0x4B }, // D/K
    { 0x46, 0x4E, 0x4B }, // L
    { 0xC6, 0x4E, 0x53 }, // L'
};



void devTunerSetIF( EnuTunerSoundSystem ucSoundSystem )
{
    U8 i, ucTemp;
    ucTemp = (ucSoundSystem==TUNER_SOUND_AUTO)?0:(ucSoundSystem)-1;
    PAL_DBG_MSG(printf("=devTunerSetIF=ucTemp=%bx\n",ucTemp));
    if( ucSoundSystem >= TUNER_SOUND_NUMS )
        ucSoundSystem = 0;
    ZL10353_RepeatControl(ENABLE);
    MDrv_Timer_Delayms(5);
    for( i = 0; i < 3; ++ i )
    {
        //printf("IF=%bx \r\n",tIFBCETable[ucTemp][i]);
        if(MDrv_IIC_WriteByte(TN_IF_I2C_ADDR, i, tIFBCETable[ucTemp][i])==FALSE)
        {
            PAL_DBG_MSG(printf("TN_IF_I2C_ADDR write Error\n"));
        }
    }
    ZL10353_RepeatControl(DISABLE);

}

void devTunerSetSubSys( EnuTunerSoundSystem ucSoundSystem )
{
    devTunerSetIF( ucSoundSystem );

    if( TUNER_SOUND_LL == ucSoundSystem )
        g_TuneFreqIF = 33.95 * 16;
    else
        g_TuneFreqIF = 38.9 * 16;
}

U8 devTunerSetFreq( U16 wFreq )
{

    g_TunerPara.ProgDivide = wFreq + g_TuneFreqIF;
    g_TunerPara.ControlInfo1 = 0x80 | TN_RSA_RSB ;

    if( wFreq < (160*16) )
        g_TunerPara.ControlInfo2 = TN_LOW_BAND;
    else if( wFreq < (442.00 * 16))
        g_TunerPara.ControlInfo2 = TN_MID_BAND;
    else
        g_TunerPara.ControlInfo2 = TN_HIGH_BAND;

    g_TunerPara.AuxilliaryByte=0x60;

    return devTunerWrite( &g_TunerPara );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -