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

📄 lcd_auto.c

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

unsigned char Min_Noise_Margin(void)
{
    unsigned char   Result, Noise;
    unsigned int    Curr_StartH, Curr_EndH;

    Result  = Measure_PositionV(VERTICAL_MARGIN);
    
    if (ERROR_SUCCEED != Result)    return Result;
	    
    if (0 == usVer_Start)
    {
        Result  = Measure_PositionV(VERTICAL_MARGIN + 0x20);
        if (ERROR_SUCCEED != Result)    return Result;
    }
    
    Noise   = 0x00;
    Result  = Measure_PositionH(Noise);
    if (ERROR_SUCCEED != Result)    return Result;
        
    Curr_StartH = usH_Start;    // Save H start position at noise margin = 0
    Curr_EndH   = usH_End;      // Save H end position at noise margin = 0

    do
    {
        Noise   = Noise + 0x10;
        Result  = Measure_PositionH(Noise);

        if (ERROR_SUCCEED != Result)    return Result;
    
        if (Curr_StartH >= usH_Start)
        {
            Curr_StartH = usH_Start;
        }
        else if (0x08 < (usH_Start - Curr_StartH))
        {
            break;  // A large gap of H start position is found.
        }
    }
    while (0x90 > Noise);

    if (0x80 < Noise)   return ERROR_ABORT;      

    while (1)
    {   
        Curr_StartH = usH_Start;
        Curr_EndH   = usH_End;

        Result  = Measure_PositionH(Noise + 0x20);
        
        if (ERROR_SUCCEED != Result)    return Result;

        // We got noise margin with stable horizontal start/end position.
        if ((Curr_EndH - Curr_StartH) == (usH_End - usH_Start) || (Curr_EndH - Curr_StartH) >= (usH_End - usH_Start + 3))
        {
            if ((HORIZONTAL_MARGIN - 0x10) > Noise)     Noise   = HORIZONTAL_MARGIN - 0x10;

            break;
        }
        
        // No stable horizontal start/end position are found.
        if (0xa0 <= Noise)  return ERROR_ABORT;

        Noise   = Noise + 0x10;        
        Result  = Measure_PositionH(Noise);

        if (ERROR_SUCCEED != Result)    return Result;
    };

    Data[0] = Noise + 0x10;

    return ERROR_SUCCEED;
}

unsigned char Read_Phase_Info(unsigned char Color)
{
    RTDSetByte(MARGIN_B_7D, Color);
    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);

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

    RTDRead(AUTO_PHASE0_88, 4, Y_INC);
    Data[4] = Data[3];
    Data[5] = Data[2];
    Data[6] = Data[1];
    Data[7] = Data[0];

    return ERROR_SUCCEED;
}

#if (AUTO_PHASE_OPTION == 1)

unsigned char Read_All_Info()
{
    unsigned long MaxSum;

    if (ERROR_SUCCEED != Read_Phase_Info(COLORS_RED))       return ERROR_INPUT;
    MaxSum  = ((unsigned long *)Data)[1] >> 1;

    if (ERROR_SUCCEED != Read_Phase_Info(COLORS_GREEN))     return ERROR_INPUT;
    MaxSum  += ((unsigned long *)Data)[1] >> 1;

    if (ERROR_SUCCEED != Read_Phase_Info(COLORS_BLUE))      return ERROR_INPUT;

    ((unsigned long *)Data)[1]  = MaxSum + (((unsigned long *)Data)[1] >> 1);

    return ERROR_SUCCEED;
}

#endif

unsigned char FindColor(void)
{
    unsigned char BestColor, SelColor;
    unsigned long MaxSum;

    RTDSetByte(DIFF_THRED_7E, 0x30);

    MaxSum      = 0;
    SelColor    = COLORS_RED;
    do
    {
        ((unsigned long*)Data)[0] = PhaseSearch(SelColor, HWAUTO_STEP_8);

        if (0xffffffffL == ((unsigned long*)Data)[0])   return COLORS_FAIL;

        if (MaxSum < ((unsigned long *)Data)[0])
        {
            BestColor   = SelColor;
            MaxSum      = ((unsigned long *)Data)[0];
        }
        if (COLORS_RED == SelColor)
            SelColor    = COLORS_GREEN;
        else if (COLORS_GREEN == SelColor)
            SelColor    = COLORS_BLUE;
        else
            break;
    }
    while (1);

    return (MaxSum ? BestColor : COLORS_NONE);
}

unsigned long PhaseSearch(unsigned char SelColor, unsigned char SelStep)
{
    unsigned long idata  ulMaxSum;
    unsigned char idata  count, best;

    RTDSetBit(MARGIN_B_7D, 0xfc, SelColor & 0x03);
    
    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
    RTDSetByte(HW_AUTO_PHASE_9E, 0x00);

#if (HARDWARE_AUTO)

    // Issac : Because H/W auto phase search may cause underflow at start and stop,
    //         frame-sync watch-dog must be disabled.
    Disable_Watch_Dog(WATCH_DOG_FRAMESYNC);

    SelStep &= 0x03;
    RTDSetByte(HW_AUTO_PHASE_9E, (SelStep & 0x03) | 0x04);

    SelStep     = (HWAUTO_STEP_8 == SelStep) ? 8 : (HWAUTO_STEP_4 == SelStep) ? 4 : (HWAUTO_STEP_2 == SelStep) ? 2 : 1;
    ulMaxSum    = 0;
    best        = 0;
    count       = 0;

    // Issac : Using Wait_For_Event(EVENT_IVS) instead of Wait_For_IVS().
    //         Because H/W auto phase search may cause underflow at start and stop. 
    //         Wait_For_Event() will not check underflow/overflow.
    Wait_For_Event(EVENT_IVS);
    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
    
    if (Wait_For_IVS() & (EVENT_UNDERFLOW | EVENT_OVERFLOW))    return 0xffffffff;

    do
    {
        if (Wait_For_IVS() & (EVENT_UNDERFLOW | EVENT_OVERFLOW))    return 0xffffffff;

        RTDRead(AUTO_PHASE0_88 + 1, 3, Y_INC);
        
        Data[4] = Data[2];
        Data[5] = Data[1];
        Data[6] = Data[0];
        Data[7] = 0;

        if (ulMaxSum < ((unsigned long *)Data)[1])
        {
            ulMaxSum    = ((unsigned long *)Data)[1];
            best        = count;
        }

        count += SelStep;
    }
    while (32 > count);

    RTDSetByte(HW_AUTO_PHASE_9E, 0x00);     // Switch back to software auto phase
    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);    

    Wait_For_Event(EVENT_IVS);

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

    Enable_Watch_Dog(WATCH_DOG_FRAMESYNC);

    Data[0] = best;

#else

    SelStep     = (HWAUTO_STEP_8 == SelStep) ? 8 : (HWAUTO_STEP_4 == SelStep) ? 4 : (HWAUTO_STEP_2 == SelStep) ? 2 : 1;
    ulMaxSum    = 0;
    best        = 0;
    count       = 0;    
    do
    {
        Set_Phase(count << 2);

        if (ERROR_SUCCEED != Read_Phase_Info(SelColor))     return 0xffffffff;

        if (ulMaxSum < ((unsigned long *)Data)[1])
        {
            ulMaxSum    = ((unsigned long *)Data)[1];
            best        = count;
        }

        count += SelStep;
    }
    while (32 > count);

    Data[0] = best;

#endif

    return bPowerDownWhenAuto ? 0xffffffff : ulMaxSum;
}


unsigned char Auto_Clock_Do(unsigned char NM, unsigned char Color)
{
    unsigned char   ucResult;
    unsigned char   count, delta, stop;  
    

    // stMUD.CLOCK must be 4N at first
    stMUD.CLOCK = (stMUD.CLOCK) & 0xfc;
    Set_Clock();

    ///////////////////////////////
    //  Measure (V) Start & End  //
    ///////////////////////////////
    ucResult    = Measure_PositionV(NM);
    if (ERROR_SUCCEED != ucResult)      return ucResult;

    delta   = (800 < usIPH_ACT_WID) ? 100 : 50;

    NM      = NM + 0x10;
    stop    = 0;
    count   = 10;
    do
    {
        ///////////////////////////////
        //  Measure (H) Start & End  //
        ///////////////////////////////
        ucResult    = Measure_PositionH(NM);
        if (ERROR_SUCCEED != ucResult)      return ucResult;
        
        usH_End     = usH_End + 1 - usH_Start;
        
        // H_Active Delta
        if (usH_End < usIPH_ACT_WID)
        {
            if ((usIPH_ACT_WID - usH_End) >= (2 * delta))
            {
                stop    = 1;
            }
            else
            {
                usH_Start   = (unsigned long)(usIPH_ACT_WID - usH_End) * (usADC_Clock + (unsigned int)stMUD.CLOCK - 128) 
                            / (unsigned long)usIPH_ACT_WID;
                usH_Start   = (usH_Start + 2) & 0xfffc;

                if ((usH_Start + stMUD.CLOCK) > (128 + delta))
                {
                    stop    = 1;
                }
                else
                {
                    stMUD.CLOCK += usH_Start;
                }
            }
        }
        else 
        {
            if ((usH_End - usIPH_ACT_WID) >= (2 * delta))
            {
                stop    = 1;
            }
            else
            {
                usH_Start   = (unsigned long)(usH_End - usIPH_ACT_WID) * (usADC_Clock + (unsigned int)stMUD.CLOCK - 128) 
                            / (unsigned long)usIPH_ACT_WID;
                usH_Start   = (usH_Start + 2) & 0xfffc;

                //if ((stMUD.CLOCK - usH_Start) < (128 - delta))
                if (stMUD.CLOCK < (usH_Start + 128 - delta))
                {
                    stop    = 1;
                }
                else
                {
                    stMUD.CLOCK -= usH_Start;
                }
            }
        }

        if (stop)   break;

        Set_Clock();

        if (0 == usH_Start)  break;
    }
    while (--count);
    
    if (0 == count || 0 != stop)    return ERROR_ABORT;

    // Prevent from 1/2-line moire and smear effect.
    if ((usH_End >= usIPH_ACT_WID && (128 + 4) == stMUD.CLOCK)
        || (usH_End < usIPH_ACT_WID && (128 - 4) == stMUD.CLOCK))
    {
        stMUD.CLOCK = 128;
        Set_Clock();

        ucResult    = Measure_PositionH(NM);
        if (ERROR_SUCCEED != ucResult)      return ucResult;

        usH_End     = usH_End + 1 - usH_Start;
    }

#if (AUTO_CLOCK_STEP < 4)

    if (COLORS_NONE == Color)
    {
        return ERROR_SUCCEED;
    }
    else
    {
        unsigned long   ulMaxVal;

        // Save 4N clock
        stop    = stMUD.CLOCK;

        stMUD.CLOCK += (usIPH_ACT_WID >= usH_End) ? 4 : 2;
        Set_Clock();

        // Set threshold for Clock Search
        RTDSetByte(DIFF_THRED_7E, 0x18);

        count       = stop;
        ulMaxVal    = 0;
        delta       = 6;    // Initial value must be (N * AUTO_CLOCK_STEP)
        do
        {	
            Data[0] = Measure_PositionH(NM);
            if (ERROR_SUCCEED != Data[0])   return ucResult;

            usH_End     = usH_End + 1 - usH_Start;
        
            if (usH_End > (usIPH_ACT_WID + 2))
            {
                ((unsigned long*)Data)[0]   = 0;
            }
            else
            {
                ((unsigned long*)Data)[0]   = PhaseSearch(Color, HWAUTO_STEP_4);

                if (0xffffffffL == ((unsigned long*)Data)[0])   return ERROR_INPUT;
            }

            if (ulMaxVal < ((unsigned long*)Data)[0])
            {
                ulMaxVal    = ((unsigned long*)Data)[0];
                count       = stMUD.CLOCK;
            }

            if (0x00 == delta)
            {
                // Check if default clock is the best when clock searching range is larger than default.
                if (128 < stMUD.CLOCK)
                {
                    stMUD.CLOCK = 128;
                    Set_Clock();
                    continue;            
                }
                break;
            }

            delta       -= AUTO_CLOCK_STEP;
            stMUD.CLOCK -= AUTO_CLOCK_STEP;
            Set_Clock();
        }
        while (1); 

        stMUD.CLOCK = (ulMaxVal > ((unsigned long)usIPH_ACT_WID << 10)) ? count : stop;
        Set_Clock();
    }

#endif

    return ERROR_SUCCEED;
}

unsigned char Auto_Phase_Do(unsigned char NM, unsigned char Color)
{
    unsigned char ucResult;
    unsigned long ulMaxSum;

    if (COLORS_NONE == Color)   return ERROR_ABORT;

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

    // Set threshold for Phase Search
    RTDSetByte(DIFF_THRED_7E, 0x40);

    ulMaxSum    = PhaseSearch(Color, HWAUTO_STEP_2);

    if (0xffffffffL == ulMaxSum)    return ERROR_INPUT;

    if (0 == ulMaxSum)    return ERROR_ABORT;
    
    // PhaseSearch() will reture the best phase into Data[0];
    ucResult    = Data[0];

#if (AUTO_PHASE_OPTION == 1)

    {
        unsigned char ucPhase, ucBest;
        unsigned long ulTemp0, ulTemp1, ulTemp2;

        ucPhase = (ucResult - 3) & 0x1f;
        Set_Phase(ucPhase << 2);

        if (ERROR_SUCCEED != Read_All_Info())   return ERROR_INPUT;
        ulTemp0 = ((unsigned long*)Data)[1];

        ucPhase = (ucPhase + 1) & 0x1f;
        Set_Phase(ucPhase << 2);

        if (ERROR_SUCCEED != Read_All_Info())   return ERROR_INPUT;
        ulTemp1 = ((unsigned long*)Data)[1];

        ucResult    = (ucResult + 3) & 0x1f;
        ulMaxSum    = 0;
        do
        {
            ucPhase = (ucPhase + 1) & 0x1f;
            Set_Phase(ucPhase << 2);

            if (ERROR_SUCCEED != Read_All_Info())   return ERROR_INPUT;
            ulTemp2 = ((unsigned long*)Data)[1];

            ((unsigned long*)Data)[0]   = ulTemp2 + ulTemp1 + ulTemp0
                                        - ((ulTemp1 > ulTemp0 ? ulTemp1 - ulTemp0 : ulTemp0 - ulTemp1) / 2)
                                        - ((ulTemp1 > ulTemp2 ? ulTemp1 - ulTemp2 : ulTemp2 - ulTemp1) / 2);
                
            if (((unsigned long*)Data)[0] > ulMaxSum)
            {
                ulMaxSum    = ((unsigned long*)Data)[0];
                ucBest      = (ucPhase - 1) & 0x1f;

⌨️ 快捷键说明

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