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

📄 lcd_auto.c

📁 Realtek 公司的RTD2523A芯片原厂source code,没有被修改过的。
💻 C
📖 第 1 页 / 共 3 页
字号:
#define __AUTO__

#include "Header\INCLUDE.H"


unsigned char Auto_Config(void)
{
    unsigned char   Result, Noise, Color, Curr_PosH, Curr_PosV, Curr_Clock, Curr_Phase;
	unsigned int    Curr_HIAS;

    // Enter Auto Progress
    bAutoInProgress     = 1;
    bPowerDownWhenAuto  = 0;

    // Save current settings
    Curr_HIAS   = usIPH_ACT_STA;
    Curr_PosH   = stMUD.H_POSITION;
    Curr_PosV   = stMUD.V_POSITION;
    Curr_Clock  = stMUD.CLOCK;
    Curr_Phase  = stMUD.PHASE;

    // IVS delay will increase when V position is larger than ucV_Max_Margin.
    // Large IVS delay may cause auto-function fail.
    if (ucV_Max_Margin < stMUD.V_POSITION)
    {
        stMUD.V_POSITION    = ucV_Max_Margin - 1;
        Set_V_Position();
    }

    // Clock and H-position limitation for low resolution
    if (800 >= usIPH_ACT_WID)
    {
        usIPH_ACT_STA   = usIPH_ACT_STA + 50;
        ucH_Min_Margin  = (128 - 100) + 50;

        if ((128 - 50) > stMUD.CLOCK || (128 + 50) < stMUD.CLOCK)   stMUD.CLOCK = 128;
    }
    stMUD.H_POSITION    = 128;
	Set_H_Position();
    Set_Clock();

    // Clear the HW auto status to prevent some un-expected event happened
    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
    RTDSetByte(HW_AUTO_PHASE_9E, 0x00);

    RTDSetByte(STATUS0_01, 0x00);  // Clear status
    RTDSetByte(STATUS1_1F, 0x00);  // Clear status

    // Do auto-config under reasonable ADC settings
    RTDCodeW(ADC_DEFAULT);

    // Get boundary of image
    Result  = Min_Noise_Margin();   
    Noise   = Data[0];

    if (ERROR_SUCCEED != Result)
    {
        stMUD.CLOCK         = Curr_Clock;
        stMUD.PHASE         = Curr_Phase;
        stMUD.H_POSITION    = Curr_PosH;
        stMUD.V_POSITION    = Curr_PosV;
    }
    else
    {
        // Select color for rough search
        Color   = FindColor();

        if (COLORS_FAIL == Color)
        {
            Result  = ERROR_INPUT;

            stMUD.CLOCK         = Curr_Clock;
            stMUD.PHASE         = Curr_Phase;
            stMUD.H_POSITION    = Curr_PosH;
            stMUD.V_POSITION    = Curr_PosV;
        }
        else
        {
            if (MODE_0640x0350x70HZ <= ucMode_Curr && MODE_0720x0400x70HZ >= ucMode_Curr)
            {
                // Restore default clock instead of doing auto-clock for DOS/BIOS mode
                stMUD.CLOCK = 128;
                Set_Clock();

                Result  = ERROR_SUCCEED;
            }
            else
            {   
                Result  = Auto_Clock_Do(Noise, Color);
            }

            if (ERROR_SUCCEED != Result)
            { 
                stMUD.CLOCK         = Curr_Clock;
                stMUD.PHASE         = Curr_Phase;
                stMUD.H_POSITION    = Curr_PosH;
                stMUD.V_POSITION    = Curr_PosV;
            }
            else
            {                
                Result  = Auto_Phase_Do(Noise, Color);

                if (ERROR_SUCCEED != Result)
                {
                    stMUD.PHASE         = Curr_Phase;
                    stMUD.H_POSITION    = Curr_PosH;
                    stMUD.V_POSITION    = Curr_PosV;
                }
                else
                {
                    Result  = Auto_Position_Do(Noise);                

                    if (ERROR_SUCCEED != Result)
                    {
                        stMUD.H_POSITION    = Curr_PosH;
                        stMUD.V_POSITION    = Curr_PosV;
                    }
                }
            }
        }
    }

    // Restore settings
    usIPH_ACT_STA       = Curr_HIAS;
    ucH_Min_Margin      = 128 - 100;

    if (ERROR_SUCCEED == Result)
    {
        Set_H_Position();
        Save_Auto_Result();
    }
    else if (ERROR_INPUT != Result)
    {        
        Set_Clock();
        Set_Phase(stMUD.PHASE);
        Set_H_Position();
        Set_V_Position();
    }

    RTDSetByte(STATUS0_01, 0x00);  // Clear status
    RTDSetByte(STATUS1_1F, 0x00);  // Clear status

    // Restore ADC Gain/Offset
    SetADC_GainOffset();
   
    // Exit Auto Progress
    bAutoInProgress = 0;

    return bPowerDownWhenAuto ? ERROR_SUCCEED : Result;
}


unsigned char Auto_Balance(void)
{
    unsigned char Result, Curr_PosV, Curr_Gain;

    bAutoInProgress = 1;

    Curr_PosV   = stMUD.V_POSITION;     // Save current stMUD.V_POSITION

    if (ucV_Max_Margin < stMUD.V_POSITION)
    {
        stMUD.V_POSITION    = ucV_Max_Margin - 1;
        Set_V_Position();
    }

    // Restore ADC gain/offset to default
    Curr_Gain       = stGUD0.CONTRAST;
    stGUD0.CONTRAST = 50;
	SetADC_GainOffset();

    // Do ADC gain/offset adjust
    Result  = Tune_Balance();

    if (ERROR_SUCCEED == Result)
    {
        stGUD0.CONTRAST         = 50;

        /*
        stGUD0.RTD_R_CONTRAST   = 50;
        stGUD0.RTD_G_CONTRAST   = 50;
        stGUD0.RTD_B_CONTRAST   = 50;
        stGUD0.RTD_R_BRIGHT     = 50;
        stGUD0.RTD_G_BRIGHT     = 50;
        stGUD0.RTD_B_BRIGHT     = 50;
        */
        
        Set_Bright_Contrast();
        SetADC_GainOffset();

        Save_GUD0();
        Save_GUD2();
    }
    else
    {
        // Restore ADC Gain/Offset
        stGUD0.CONTRAST = Curr_Gain;

        Load_GUD2();
        SetADC_GainOffset();
    }

    // Restore vertical position
    stMUD.V_POSITION    = Curr_PosV;
    Set_V_Position();

    bAutoInProgress = 0;

    return Result;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Sub-Routine called by Auto_Config() and Auto_Balance()
///////////////////////////////////////////////////////////////////////////////////////////

void Wait_Finish(void)
{
    unsigned char   Wait_Time_Cnt, IVS_Event;

	RTDSetByte(STATUS0_01, 0x00);   // Clear status  
    RTDSetByte(STATUS1_1F, 0x00);   // Clear status
    
    Wait_Time_Cnt   = 50;           // Auto timeout 50ms
    IVS_Event       = 25;           // IVS timeout 25ms 
    do
    {  
        Delay_Xms(1);

        RTDRead(STATUS1_1F, 1, N_INC);      // Read Status

        if (Data[0] & EVENT_IVS)
        {
            RTDSetByte(STATUS1_1F, 0x00);   // Clear status
            IVS_Event   = 25;
        }
        else
        {
            IVS_Event   = IVS_Event - 1;
        }

        if (0 == IVS_Event || (Data[0] & (EVENT_UNDERFLOW | EVENT_OVERFLOW)))
        {
            Data[0] = ERROR_INPUT;

            return;
        }

        RTDRead(AUTO_ADJ_CTRL_7F, 1, N_INC);
    }
    while ((Data[0] & 0x01) && (--Wait_Time_Cnt) && (!bPowerDownWhenAuto));
    
    RTDRead(STATUS0_01, 1, N_INC);  // Read Status

    RTDSetByte(STATUS0_01, 0x00);   // Clear Status

    // Return non-zero value in Data[0] if :
    // 1. IVS or IHS changed
    // 2. Auto-Phase Tracking timeout
	
    Data[0] = ((Data[0] & 0x63) || (0 == Wait_Time_Cnt) || bPowerDownWhenAuto) ? ERROR_INPUT : ERROR_SUCCEED;
}

#if (HARDWARE_AUTO)

unsigned char Wait_For_IVS(void)
{
    unsigned char ucTimeOut = 25;

    RTDSetByte(STATUS1_1F, 0x00);
   	do
    {
        Delay_Xms(1);

        RTDRead(STATUS1_1F, 1, N_INC);        
        Data[0] &= (EVENT_IVS | EVENT_UNDERFLOW | EVENT_OVERFLOW);
   	}
    while ((0 == Data[0]) && (--ucTimeOut));

    return Data[0];
}

#endif


unsigned char Measure_PositionV(unsigned char NM_V)
{
    unsigned int    usLBound, usRBound;

    RTDRead(MEAS_HI_51, 0x02, Y_INC);
    Data[2] = Data[1] & 0x0f;
    Data[3] = Data[0];

    usRBound    = usADC_Clock + (unsigned int)stMUD.CLOCK - 128;
    usLBound    = (unsigned long)usRBound * ((unsigned int *)Data)[1] / usHsync;

    // Original formula : 
    // usRBound    = usRBound - 2 - (PROGRAM_HDELAY - MEASURE_HDEALY) - (stMUD.H_POSITION - ucH_Min_Margin);
    // usLBound    = usLBound + 20 - (PROGRAM_HDELAY - MEASURE_HDEALY) - (stMUD.H_POSITION - ucH_Min_Margin);

    usRBound    = usRBound - 2 + MEASURE_HDEALY - PROGRAM_HDELAY + ucH_Min_Margin - stMUD.H_POSITION;
    usLBound    = usLBound + 20 + ucH_Min_Margin + MEASURE_HDEALY;
    usLBound    = usLBound > ((unsigned int)stMUD.H_POSITION + PROGRAM_HDELAY) ? (usLBound - PROGRAM_HDELAY - stMUD.H_POSITION) : 1;

    NM_V        = NM_V & 0xfc;

    Data[0]     = 6;
    Data[1]     = Y_INC;
    Data[2]     = H_BND_STA_L_75;
    Data[3]     = (unsigned char)usLBound;
    Data[4]     = (unsigned char)usRBound;
    Data[5]     = ((unsigned char)(usLBound >> 4) & 0x70) | ((unsigned char)(usRBound >> 8) & 0x0f);    
    Data[6]     = 8;
    Data[7]     = Y_INC;
    Data[8]     = MARGIN_R_7B;
    Data[9]     = NM_V;
    Data[10]    = NM_V | PIXEL_1;
    Data[11]    = NM_V;
    Data[12]    = 0x00;
    Data[13]    = 0x01;
    Data[14]    = 0;
    RTDWrite(Data);
    
	Wait_Finish();

    if (ERROR_SUCCEED != Data[0])   return Data[0];

    RTDRead(VER_START_80, 4, Y_INC);

    // Translate byte order : RTD little indian -> 8051 big indian
    Data[6] = Data[1] & 0x0f;
    Data[7] = Data[0];
    Data[8] = Data[3] & 0x0f;
    Data[9] = Data[2];

    // V Start/End should subtract 1
    usVer_Start     = ((unsigned int *)Data)[3] ? ((unsigned int *)Data)[3] - 1 : 0;
    usVer_End       = ((unsigned int *)Data)[4] ? ((unsigned int *)Data)[4] - 1 : 0;

    // Check all black
    if (0x0000 == usVer_End)    return  ERROR_ABORT;

    // To prevent from noise induced by VSYNC
    if (9 > usVer_Start + PROGRAM_VDELAY)
	{
        ((unsigned int *)Data)[3]	= 9 - PROGRAM_VDELAY;

        usVer_Start = usVer_End - usIPV_ACT_LEN + 1;
	}
    else if (usVer_End > (usVer_Start + usIPV_ACT_LEN - 1))
    {
        usVer_End   = usVer_Start + usIPV_ACT_LEN - 1;

        ((unsigned int *)Data)[4]   = usVer_End;
    }

    // Update auto-tracking window vertical range
    Data[0] = 6;
    Data[1] = Y_INC;
    Data[2] = V_BND_STA_L_78;
    Data[3] = Data[7];    
    Data[4] = Data[9];
    Data[5] = (Data[6] << 4) + Data[8];
    Data[6] = 0;
    RTDWrite(Data);

    return ERROR_SUCCEED;
}


unsigned char Measure_PositionH(unsigned char NM_H)
{
    unsigned int    usLBound, usRBound;

    RTDRead(MEAS_HI_51, 2, Y_INC);
    Data[2] = Data[1] & 0x0f;
    Data[3] = Data[0];

    usRBound    = usADC_Clock + (unsigned int)stMUD.CLOCK - 128;                    // Totol Clock Number
    usLBound    = (unsigned long)usRBound * ((unsigned int *)Data)[1] / usHsync;    // Clock number in HSYNC pulse

    RTDRead(IHS_DELAY_8D, 1, N_INC);

    //usRBound    = usRBound - 2 + MEASURE_HDEALY - PROGRAM_HDELAY - stMUD.H_POSITION + ucH_Min_Margin;
    usRBound    = (usRBound + MEASURE_HDEALY - Data[0]) - 2;

    //usLBound    = usLBound + 20 + MEASURE_HDEALY - Data[0];
    usLBound    = (usLBound + 20 + MEASURE_HDEALY) > Data[0] ? (usLBound + 20 + MEASURE_HDEALY) - Data[0] : 0x0001;

    NM_H        = NM_H & 0xfc;

    Data[0]     = 6;
    Data[1]     = Y_INC;
    Data[2]     = H_BND_STA_L_75;
    Data[3]     = (unsigned char)usLBound;
    Data[4]     = (unsigned char)usRBound;
    Data[5]     = ((unsigned char)(usLBound >> 4) & 0x70) | ((unsigned char)(usRBound >> 8) & 0x0f);    
    Data[6]     = 8;
    Data[7]     = Y_INC;
    Data[8]     = MARGIN_R_7B;
    Data[9]     = NM_H;
    Data[10]    = NM_H;
    Data[11]    = NM_H;
    Data[12]    = 0x00;
    Data[13]    = 0x01;
    Data[14]    = 0;
    RTDWrite(Data);

    Wait_Finish();

    if (ERROR_SUCCEED != Data[0])   return Data[0];

    RTDRead(HOR_START_84, 4, Y_INC);

    // Translate byte order : RTD little indian -> 8051 big indian
    Data[4] = Data[3] & 0x0f;
    Data[5] = Data[2];
    Data[2] = Data[1] & 0x0f;
    Data[3] = Data[0];
    
    if (0x07FF <= ((unsigned int *)Data)[1])     return  ERROR_ABORT;
    
    // In low speed capture, there are 3-clock extra capture delay.
    RTDRead(VGIP_CTRL_04, 1, N_INC);
    NM_H    = (0x08 == (Data[0] & 0x0c)) ? 0x03 : 0x00;

    //usH_Start   = ((unsigned int *)Data)[1] - (MEAS_H_STA_OFFSET - NM_H);
    //usH_End     = ((unsigned int *)Data)[1] - (MEAS_H_END_OFFSET - NM_H);

    usH_Start   = (((unsigned int *)Data)[1] + NM_H) > MEAS_H_STA_OFFSET
                ? (((unsigned int *)Data)[1] + NM_H) - MEAS_H_STA_OFFSET : 0x0000;
    usH_End     = (((unsigned int *)Data)[2] + NM_H) > MEAS_H_END_OFFSET
                ? (((unsigned int *)Data)[2] + NM_H) - MEAS_H_END_OFFSET : 0x0fff;

    return ERROR_SUCCEED;
}

// Issac : Only for Auto Balance
unsigned char Measure_PositionN(unsigned char NM)
{
    unsigned char Result;

    Result  = Measure_PositionV(NM);
    if (ERROR_SUCCEED != Result)    return Result;

    Result  = Measure_PositionH(NM);
    if (ERROR_SUCCEED != Result)    return Result;
        
    RTDRead(VER_START_80, 4, Y_INC);

    // Translate byte order : RTD little indian -> 8051 big indian
    Data[6] = Data[1] & 0x0f;
    Data[7] = Data[0];
    Data[8] = Data[3] & 0x0f;
    Data[9] = Data[2];

    usVer_Start = ((unsigned int *)Data)[3];
    usVer_End   = ((unsigned int *)Data)[4];

    RTDRead(HOR_START_84, 4, Y_INC);

    // Translate byte order : RTD little indian -> 8051 big indian
    Data[4] = Data[3] & 0x0f;
    Data[5] = Data[2];
    Data[2] = Data[1] & 0x0f;
    Data[3] = Data[0];
    
    usH_Start   = ((unsigned int *)Data)[1];
    usH_End     = ((unsigned int *)Data)[2];
    
    return ERROR_SUCCEED;
}

⌨️ 快捷键说明

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