Lcd_auto.c
上传用户:xmyjxjd
上传日期:2013-05-04
资源大小:1517k
文件大小:79k
开发平台:

C/C++

  1. #define __AUTO__
  2. #include "reg52.h"
  3. #include "HeaderMAIN_DEF.h"
  4. #include "HeaderACCESS.H"
  5. #include "HeaderLCD_MAIN.H"
  6. #include "HeaderCONFIG.H"
  7. #include "HeaderLCD_FUNC.H"
  8. #include "HeaderLCD_AUTO.H"
  9. #include "HeaderLCD_OSD.H"
  10. void Wait_Finish(void)
  11. {
  12.     unsigned char   Wait_Time_Cnt, IVS_Event;
  13. RTDSetByte(STATUS0_01, 0x00);  // Clear status  
  14.     RTDSetByte(STATUS1_1F, 0x00);  // Clear status
  15.     
  16.     Wait_Time_Cnt   = 60;           // Auto-Phase timeout 60ms
  17.     IVS_Event       = 25;           // IVS timeout 25ms 
  18.     do
  19.     {  
  20.          Delay_Xms(1);
  21.      
  22. /*
  23. #if(AS_NON_FRAMESYNC == 0)
  24.          RTDRead(STATUS0_01, 1, N_INC);  // Get status        
  25.         if (Data[0] & 0x63)
  26.         {
  27. #if(MCU_TYPE == MCU_WINBOND)
  28.         bLIGHT_PWR  = LIGHT_OFF;
  29. #else
  30.         MCU_WriteBacklightPower(LIGHT_OFF);
  31. #endif
  32.             RTDCodeW(FreeV);
  33.             Data[0] = ERROR_INPUT;
  34.             RTDSetByte(STATUS0_01, 0x00);  // Clear status  
  35.             return;
  36.         }
  37. #endif
  38.       //Delay_Xms(2);
  39. #if(MCU_TYPE == MCU_MTV512)
  40.       RTDSetByte(STATUS1_1F, 0x00);  // Clear status
  41. #endif
  42. #if(AS_NON_FRAMESYNC == 0 || AS_DV_TOTAL == 0)
  43.         RTDRead(STATUS1_1F, 1, N_INC);  // Get status
  44.         
  45.         if ((Data[0] & (EVENT_UNDERFLOW | EVENT_OVERFLOW)) || (0 == --IVS_Event))
  46.         {
  47.          
  48. #if(MCU_TYPE == MCU_WINBOND)
  49.         bLIGHT_PWR  = LIGHT_OFF;
  50. #else
  51.         MCU_WriteBacklightPower(LIGHT_OFF);
  52. #endif
  53.             RTDCodeW(FreeV);
  54.             Data[0] = ERROR_INPUT;
  55. RTDSetByte(STATUS1_1F,0x00); //Event happened, write once to clear the status
  56.             return;
  57.         }
  58.         else if (Data[0] & (EVENT_IVS | EVENT_IEN_START))
  59.         {
  60.             IVS_Event   = 25;       // IVS timeout 25ms 
  61. RTDSetByte(STATUS1_1F,0x00); //Event happened, write once to clear the status
  62.         }
  63. #endif
  64. */
  65.         RTDRead(AUTO_ADJ_CTRL_7F, 1, N_INC);
  66.     }
  67.     while ((Data[0] & 0x01) && (--Wait_Time_Cnt));
  68.     
  69.     RTDRead(STATUS0_01, 1, N_INC);  // Get status
  70. if(Data[0])
  71. RTDSetByte(STATUS0_01,0x00); //Event happened, write once to clear the status
  72.     // Return non-zero value in Data[0] if :
  73.     // 1. IVS or IHS changed
  74.     // 2. Buffer underflow or overflow
  75.     // 3. Auto-Phase Tracking timeout
  76.     Data[0] = (Data[0] & 0x63) ? ERROR_INPUT : (0 == Wait_Time_Cnt) ? ERROR_TIMEOUT : ERROR_SUCCEED;
  77. }
  78. #if(HARDWARE_AUTO)
  79. void Wait_For_IVS(void)
  80. {
  81.    unsigned char t;
  82. t = 50;
  83. RTDSetByte(0x1f,0x00);
  84.     do
  85. {
  86.     RTDRead(0x1f, 1, Y_INC);
  87. Data[0] = Data[0] & EVENT_IVS;
  88. //t--;
  89. Delay_Xms(1);
  90.     }while((Data[0] == 0) && (t--));
  91. }
  92. #endif
  93. //--------------------Measure Vertical Position---------------------//
  94. // Return Message => ERROR_SUCCESS   : Success                      //
  95. //                   ERROR_INPUT     : 1. IVS or IHS changed        //
  96. //                                     2. underflow or overflow     //
  97. //                   ERROR_TIMEOUT   : Measure Time_Out             //
  98. //                   ERROR_NOTACTIVE : No Avtive Image              //
  99. //------------------------------------------------------------------//
  100. unsigned char Measure_PositionV(unsigned char NM_V)
  101. {
  102.     unsigned int    usLBound, usRBound;
  103.     RTDRead(MEAS_HI_51, 0x02, Y_INC);
  104.     Data[2] = Data[1] & 0x0f;
  105.     Data[3] = Data[0];
  106.     usRBound    = usADC_Clock + (unsigned int)stMUD.CLOCK - 128;
  107.     usLBound    = (unsigned long)usRBound * ((unsigned int *)Data)[1] / usStdHS;
  108.     // Original formula : 
  109.     // usRBound    = usRBound - 2 - (PROGRAM_HDELAY - MEASURE_HDEALY) - (stMUD.H_POSITION - ucH_Min_Margin);
  110.     // usLBound    = usLBound + 20 - (PROGRAM_HDELAY - MEASURE_HDEALY) - (stMUD.H_POSITION - ucH_Min_Margin);
  111.     usRBound    = usRBound - 2 + MEASURE_HDEALY - PROGRAM_HDELAY + ucH_Min_Margin - stMUD.H_POSITION;
  112.     usLBound    = usLBound + 20 + ucH_Min_Margin + MEASURE_HDEALY;
  113.     usLBound    = usLBound > ((unsigned int)stMUD.H_POSITION + PROGRAM_HDELAY) ? (usLBound - PROGRAM_HDELAY - stMUD.H_POSITION) : 1;
  114.     NM_V        = NM_V & 0xfc;
  115.     Data[0]     = 6;
  116.     Data[1]     = Y_INC;
  117.     Data[2]     = H_BND_STA_L_75;
  118.     Data[3]     = (unsigned char)usLBound;
  119.     Data[4]     = (unsigned char)usRBound;
  120.     Data[5]     = ((unsigned char)(usLBound >> 4) & 0x70) | ((unsigned char)(usRBound >> 8) & 0x0f);    
  121.     Data[6]     = 8;
  122.     Data[7]     = Y_INC;
  123.     Data[8]     = MARGIN_R_7B;
  124.     Data[9]     = NM_V;
  125.     Data[10]    = NM_V | PIXEL_1;
  126.     Data[11]    = NM_V;
  127.     Data[12]    = 0x00;
  128.     Data[13]    = 0x01;
  129.     Data[14]    = 0;
  130.     RTDWrite(Data);
  131.     
  132. Wait_Finish();
  133.     if (ERROR_SUCCEED != Data[0])   return Data[0];
  134.     RTDRead(VER_START_80, 4, Y_INC);
  135.     // Translate byte order : RTD little indian -> 8051 big indian
  136.     Data[6] = Data[1] & 0x0f;
  137.     Data[7] = Data[0];
  138.     Data[8] = Data[3] & 0x0f;
  139.     Data[9] = Data[2];
  140.     // V Start/End should subtract 1
  141.     usVer_Start     = ((unsigned int *)Data)[3] ? ((unsigned int *)Data)[3] - 1 : 0;
  142.     usVer_End       = ((unsigned int *)Data)[4] ? ((unsigned int *)Data)[4] - 1 : 0;
  143.     // Check all black
  144.     if (0x0000 == usVer_End)    return  ERROR_NOTACTIVE;
  145. /*
  146.     // Issac 2002/10/15
  147.     // To prevent from noise induced by VSYNC
  148.     if (usVer_End > (usVer_Start + usIPV_ACT_LEN - 1))
  149.     {
  150.         usVer_End   = usVer_Start + usIPV_ACT_LEN - 1;
  151.         ((unsigned int *)Data)[4]   = usVer_End;
  152.     }
  153. */
  154. if ((9 - PROGRAM_VDELAY) > usVer_Start)
  155. {
  156.     ((unsigned int *)Data)[3] = 9 - PROGRAM_VDELAY;
  157. }
  158. else
  159. {
  160.         // To prevent from noise induced by VSYNC
  161.         if (usVer_End > (usVer_Start + usIPV_ACT_LEN - 1))
  162.         {
  163.             usVer_End   = usVer_Start + usIPV_ACT_LEN - 1;
  164.             ((unsigned int *)Data)[4]   = usVer_End;
  165.         }
  166. }
  167.     // Update auto-tracking window vertical range
  168.     Data[0] = 6;
  169.     Data[1] = Y_INC;
  170.     Data[2] = V_BND_STA_L_78;
  171.     Data[3] = Data[7];    
  172.     Data[4] = Data[9];
  173.     Data[5] = (Data[6] << 4) + Data[8];
  174.     Data[6] = 0;
  175.     RTDWrite(Data);
  176.     return ERROR_SUCCEED;
  177. }
  178. //--------------------Measure Horizontal Position-------------------//
  179. // Return Message => ERROR_SUCCESS   : Success                      //
  180. //                   ERROR_INPUT     : 1. IVS or IHS changed        //
  181. //                                     2. underflow or overflow     //
  182. //                   ERROR_TIMEOUT   : Measure Time_Out             //
  183. //                   ERROR_NOTACTIVE : No Avtive Image              //
  184. //------------------------------------------------------------------//
  185. unsigned char Measure_PositionH(unsigned char NM_H)
  186. {
  187.     unsigned int    usLBound, usRBound;
  188.     RTDRead(MEAS_HI_51, 0x02, Y_INC);
  189.     Data[2] = Data[1] & 0x0f;
  190.     Data[3] = Data[0];
  191.     usRBound    = usADC_Clock + (unsigned int)stMUD.CLOCK - 128;
  192.     usLBound    = (unsigned long)usRBound * ((unsigned int *)Data)[1] / usStdHS;
  193.     usRBound    = usRBound - 2 + MEASURE_HDEALY - PROGRAM_HDELAY + ucH_Min_Margin - stMUD.H_POSITION;
  194.     usLBound    = usLBound + 20 + ucH_Min_Margin + MEASURE_HDEALY;
  195.     usLBound    = usLBound > ((unsigned int)stMUD.H_POSITION + PROGRAM_HDELAY) ? (usLBound - PROGRAM_HDELAY - stMUD.H_POSITION) : 1;
  196.     NM_H        = NM_H & 0xfc;
  197.     Data[0]     = 6;
  198.     Data[1]     = Y_INC;
  199.     Data[2]     = H_BND_STA_L_75;
  200.     Data[3]     = (unsigned char)usLBound;
  201.     Data[4]     = (unsigned char)usRBound;
  202.     Data[5]     = ((unsigned char)(usLBound >> 4) & 0x70) | ((unsigned char)(usRBound >> 8) & 0x0f);    
  203.     Data[6]     = 8;
  204.     Data[7]     = Y_INC;
  205.     Data[8]     = MARGIN_R_7B;
  206.     Data[9]     = NM_H;
  207.     Data[10]    = NM_H;
  208.     Data[11]    = NM_H;
  209.     Data[12]    = 0x00;
  210.     Data[13]    = 0x01;
  211.     Data[14]    = 0;
  212.     RTDWrite(Data);
  213.     Wait_Finish();
  214.     if (ERROR_SUCCEED != Data[0])   return Data[0];
  215.     RTDRead(HOR_START_84, 4, Y_INC);
  216.     // Translate byte order : RTD little indian -> 8051 big indian
  217.     Data[4] = Data[3] & 0x0f;
  218.     Data[5] = Data[2];
  219.     Data[2] = Data[1] & 0x0f;
  220.     Data[3] = Data[0];
  221.     
  222.     if (0x07FF <= ((unsigned int *)Data)[1])     return  ERROR_NOTACTIVE;
  223.     
  224.     RTDRead(VGIP_CTRL_04, 1, N_INC);
  225.     //if (0x14 == (Data[0] & 0x1c))
  226. if (0x08 == (Data[0] & 0x0c))
  227.     {
  228.         ((unsigned int *)Data)[1]   += 0x03;
  229.         ((unsigned int *)Data)[2]   += 0x03;
  230.     }
  231. /*  
  232.     usH_Start   = MEAS_H_STA_OFFSET < ((unsigned int *)Data)[1] ? ((unsigned int *)Data)[1] - MEAS_H_STA_OFFSET : 0x0000;
  233.     usH_End     = MEAS_H_END_OFFSET < ((unsigned int *)Data)[2] ? ((unsigned int *)Data)[2] - MEAS_H_END_OFFSET : 0x0fff;
  234.     if (0x0000 != usH_Start)    usH_Start   = usH_Start + stMUD.H_POSITION - 128;
  235.     if (0x0fff != usH_End)      usH_End     = usH_End + stMUD.H_POSITION - 128;
  236. */        
  237.     usH_Start   = (((unsigned int *)Data)[1] + stMUD.H_POSITION) >= (128 + MEAS_H_STA_OFFSET)
  238.                 ? (((unsigned int *)Data)[1] + stMUD.H_POSITION) - (128 + MEAS_H_STA_OFFSET) : 0x0000;
  239.     usH_End     = (((unsigned int *)Data)[2] + stMUD.H_POSITION) >= (128 + MEAS_H_END_OFFSET)
  240.                 ? (((unsigned int *)Data)[2] + stMUD.H_POSITION) - (128 + MEAS_H_END_OFFSET) : 0x0fff;
  241.     return ERROR_SUCCEED;
  242. }
  243. //---------------Measure Vertical & Horizontal Position-------------//
  244. // Return Message => ERROR_SUCCESS   : Success                      //
  245. //                   ERROR_INPUT     : 1. IVS or IHS changed        //
  246. //                                     2. underflow or overflow     //
  247. //                   ERROR_TIMEOUT   : Measure Time_Out             //
  248. //                   ERROR_NOTACTIVE : No Avtive Image              //
  249. //------------------------------------------------------------------//
  250. unsigned char Measure_PositionN(unsigned char NM)
  251. {
  252.     unsigned char Result;
  253.     
  254.     Result  = Measure_PositionV(NM);
  255.     if (ERROR_SUCCEED == Result)    
  256.     {
  257.         Result  = Measure_PositionH(NM);
  258.     }
  259.         
  260.     return Result;
  261. }
  262. /*
  263. //------------------------------------------------------------------//
  264. //                           Auto Clock                             //
  265. //------------------------------------------------------------------//
  266. unsigned char Auto_Clock(void)
  267. {
  268.     unsigned char   Result, Curr_PosH, Curr_PosV, Curr_Clock, Curr_Phase;   
  269.     
  270.     bAutoInProgress = 1;
  271.     
  272.     Curr_PosH   = stMUD.H_POSITION;     // Save current stMUD.H_POSITION
  273.     Curr_PosV   = stMUD.V_POSITION;     // Save current stMUD.V_POSITION
  274.     Curr_Clock  = stMUD.CLOCK;          // Save current stMUD.CLOCK 
  275.     Curr_Phase  = stMUD.PHASE;          // Save current stMUD.PHASE
  276.     if (ucV_Max_Margin < stMUD.V_POSITION)
  277.     {
  278.         stMUD.V_POSITION    = ucV_Max_Margin;
  279.         Set_V_Position();
  280.     }
  281.     RTDCodeW(ADC_DEFAULT);
  282.     ///////////////////////////////
  283.     //   Measure  NOISE_MARGIN   //
  284.     ///////////////////////////////
  285.     Result      = Min_Noise_Margin();   // Data[0] : Noise Margin
  286.     
  287.     if (ERROR_SUCCEED == (Result & 0x80))
  288.     {
  289.         Result  = Data[0];
  290.         stMUD.CLOCK &= 0xfc;    // stMUD.CLOCK must be times of 4
  291.         if (stMUD.CLOCK != Curr_Clock || 28 > stMUD.CLOCK || 228 < stMUD.CLOCK)
  292.         {
  293.             Set_Clock();
  294.         }
  295.         
  296.         ///////////////////////////////
  297.         //       Adjust Clock        //
  298.         ///////////////////////////////
  299.         Result  = Auto_Clock_Do(Result);
  300.         
  301.         if (ERROR_SUCCEED != (Result & 0x80))
  302.         {
  303.             if (stMUD.CLOCK != Curr_Clock)
  304.             {   
  305.                 // Fail to find out suitable clock. Restore original clock and H position.
  306.                 stMUD.CLOCK         = Curr_Clock;
  307.                 stMUD.H_POSITION    = Curr_PosH;
  308.                 Set_Clock();
  309.                 Set_H_Position();
  310.             }
  311.         }
  312.         else
  313.         {
  314.             if (stMUD.CLOCK != Curr_Clock)
  315.             {
  316.                 stMUD.H_POSITION    = usH_Start + 128 + 64 - usIPH_ACT_STA - (stMUD.CLOCK >> 1);
  317.                 if (ucH_Max_Margin < stMUD.H_POSITION)
  318.                     stMUD.H_POSITION    = ucH_Max_Margin;
  319.                 else if (ucH_Min_Margin > stMUD.H_POSITION)
  320.                     stMUD.H_POSITION    = ucH_Min_Margin;
  321.                 Set_H_Position();
  322.                 Save_MUD(ucMode_Curr);
  323.             }
  324.         }
  325.     }
  326.     // Restore ADC Gain/Offset
  327.     SetADC_GainOffset();
  328.     
  329.     // Restore ADC phase 
  330.     stMUD.PHASE = Curr_Phase;
  331.     Set_Phase(stMUD.PHASE);
  332.     // Restore vertical position
  333.     if (Curr_PosV != stMUD.V_POSITION)
  334.     {
  335.         stMUD.V_POSITION    = Curr_PosV;
  336.         Set_V_Position();
  337.     }
  338.     bAutoInProgress = 0;
  339.     return Result;
  340. }
  341. */
  342. void Read_Auto_Info(unsigned char index)
  343. {
  344.      if(index == 0) return;
  345.  RTDRead(AUTO_PHASE0_88, 4, Y_INC);
  346.       Data[index << 2] = Data[3];
  347.       Data[(index << 2) + 1] = Data[2];
  348.       Data[(index << 2) + 2] = Data[1];
  349.       Data[(index << 2) + 3] = Data[0];
  350. }
  351. unsigned char FindColor()
  352. {
  353. unsigned long ulTemp0;
  354. unsigned char ucDetect,ucResult,ucPhase;
  355. RTDSetByte(DIFF_THRED_7E, 0x28);
  356.     ulTemp0     = 0;
  357.     ucDetect    = 0x77;
  358.     do
  359.     {
  360.         ucResult    = COLORS_BLUE;
  361.         ucPhase     = COLORS_BLUE;
  362.         do
  363.         {
  364.             RTDSetByte(MARGIN_B_7D, ucPhase);
  365.             RTDSetByte(AUTO_ADJ_CTRL_7F, ucDetect);
  366.             Wait_Finish();
  367.             if (ERROR_SUCCEED != Data[0])   return Data[0];
  368.             Read_Auto_Info(1);
  369.             if (ulTemp0 < ((unsigned long *)Data)[1])
  370.             {
  371.                 ulTemp0     = ((unsigned long *)Data)[1];
  372.                 ucResult    = ucPhase;
  373.                 if (0x8000 < ulTemp0)   break;
  374.             }
  375.             if (COLORS_BLUE == ucPhase)
  376.                 ucPhase = COLORS_GREEN;
  377.             else if (COLORS_GREEN == ucPhase)
  378.                 ucPhase = COLORS_RED;
  379.             else
  380.                 break;
  381.         }
  382.         while (1);
  383.         if (0 != ulTemp0 || 0x7b != ucDetect)   break;
  384.         ucDetect    = 0x77;
  385.     }
  386.     while (1);
  387.     return ERROR_SUCCEED;
  388. }
  389. unsigned long GetMaxSum(unsigned char select)
  390. {
  391.    unsigned char ucPhase,ucDetect;
  392.    unsigned long ulTemp0;
  393.    ucPhase = 0; //0,8,16,24
  394.    ulTemp0 = 0;
  395.    Set_Phase(ucPhase);
  396.    ucDetect    = (select == 0) ? 0x77 : 0x7b;
  397.    
  398. #if(HARDWARE_AUTO)
  399.    RTDSetByte(HW_AUTO_PHASE_9E,0x07);  //Step 8 auto phase
  400.    Wait_For_IVS();
  401.    //Wait_For_Event(EVENT_IVS);
  402.    RTDSetByte(AUTO_ADJ_CTRL_7F, ucDetect);  //Auto start
  403.    //Wait_For_Event(EVENT_IVS);
  404.    Wait_For_IVS();
  405.    for(ucPhase = 0;ucPhase < 4; ucPhase++)
  406.    {
  407.        //Wait_For_Event(EVENT_IVS);
  408.    Wait_For_IVS();
  409.        Read_Auto_Info(1);
  410.        if(ulTemp0 < ((unsigned long *)Data)[1])
  411.        {
  412.          ulTemp0   = ((unsigned long *)Data)[1] & 0xffffff00;
  413.        }
  414.    }
  415.    RTDSetByte(HW_AUTO_PHASE_9E,0x00);  //Switch back to software auto phase
  416.    Wait_Finish();
  417.    if(ERROR_SUCCEED != Data[0])     return (Data[0] & 0x000000ff);
  418.    
  419. #else
  420.    while(1)
  421.    {
  422.       RTDSetByte(AUTO_ADJ_CTRL_7F, ucDetect);
  423.       Wait_Finish();
  424.       if (ERROR_SUCCEED != Data[0])   return Data[0];
  425.       Read_Auto_Info(1);
  426.    if (ulTemp0 < ((unsigned long *)Data)[1])
  427.        {
  428.                 ulTemp0     = ((unsigned long *)Data)[1];
  429.        }
  430.    ucPhase += 0x20;
  431.    if(ucPhase > 0x60)
  432.         break;
  433.    Set_Phase(ucPhase);
  434. }
  435. #endif
  436.     return ulTemp0;
  437. }
  438. //------------------------------------------------------------------//
  439. // Return Message => ERROR_SUCCESS   : Success                      //
  440. //                   ERROR_TOO_SMALL : Measure Result << ACT_WIDTH  //
  441. //                   ERROR_TOO_BIG   : Measure Result >> ACT_WIDTH  //
  442. //                   ERROR_INPUT     : 1. IVS or IHS changed        //
  443. //                                     2. underflow or overflow     //
  444. //                   ERROR_TIMEOUT   : Measure Time_Out             //
  445. //                                     Process Time_Out             //
  446. //                   ERROR_NOTACTIVE : No Avtive Image              //
  447. //------------------------------------------------------------------//
  448. unsigned char Auto_Clock_Do(unsigned char NM)
  449. {
  450. #if(0)
  451.     unsigned char   ucResult;
  452.     unsigned char   count, delta, stop;    
  453.         
  454.     ///////////////////////////////
  455.     //  Measure (V) Start & End  //
  456.     ///////////////////////////////
  457.     ucResult    = Measure_PositionV(NM);
  458.     if (ERROR_SUCCEED != (ucResult & 0x80))
  459.     {
  460.         if (ERROR_NOTACTIVE == ucResult)
  461.         {
  462.             if (0x80 < stMUD.CLOCK)
  463.             {
  464.                 stMUD.CLOCK = 0x80;
  465.                 Set_H_Position();
  466.                 Set_Clock();
  467.             }
  468.             else
  469.             {
  470.                 stMUD.CLOCK = 0x80;
  471.                 Set_Clock();
  472.                 Set_H_Position();
  473.             }
  474.             ucResult    = Measure_PositionV(NM);
  475.             
  476.             if (ERROR_SUCCEED != (ucResult & 0x80))     return ucResult;
  477.         }
  478.         else
  479.             return ucResult;
  480.     }
  481.     NM      = NM + 0x10;    // See Min_Noise_Margin(). Horizontal Measure Result is the same when applying (NM + 0x10)
  482.     count   = 10;
  483.     do
  484.     {
  485.         ///////////////////////////////
  486.         //  Measure (H) Start & End  //
  487.         ///////////////////////////////
  488.         ucResult    = Measure_PositionH(NM);
  489.         if (ERROR_SUCCEED != (ucResult & 0x80))     return ucResult;
  490.         
  491.         usH_End = usH_End + 1 - usH_Start;
  492.           
  493.         // H_Active Delta
  494.         if (usH_End < usIPH_ACT_WID)
  495.             delta = (usIPH_ACT_WID - usH_End > 0x00ff) ? 0xff : (unsigned char)(usIPH_ACT_WID - usH_End);
  496.         else 
  497.             delta = (usH_End - usIPH_ACT_WID > 0x00ff) ? 0xff : (unsigned char)(usH_End - usIPH_ACT_WID);
  498.         if (0xc8 < delta)       // The difference is too large to fine-tune.
  499.         {
  500.             if (10 == count)
  501.             {
  502.                 if (0x80 < stMUD.CLOCK)
  503.                 {
  504.                     stMUD.CLOCK = 0x80;
  505.                     Set_H_Position();
  506.                     Set_Clock();
  507.                 }
  508.                 else
  509.                 {
  510.                     stMUD.CLOCK = 0x80;
  511.                     Set_Clock();
  512.                     Set_H_Position();
  513.                 }
  514.                 continue;
  515.             }
  516.             else
  517.                 return (usH_End < usIPH_ACT_WID) ? ERROR_TOO_SMALL : ERROR_TOO_BIG;
  518.         }
  519.         
  520.         if (2 >= delta)     break;  // 1023,1024,1025,1026,1027
  521.         
  522.         delta   = (delta + (delta >> 2) + 2) & 0xfc;  // 4n number
  523. #if(ALIGN_LEFT == CLOCK_ALIGN)
  524.         // Adjust Clock
  525.         if (usH_End < usIPH_ACT_WID)    // delta < 0, Measure < Active
  526.         {
  527.             if ((178 - stMUD.CLOCK) < delta)    return ERROR_TOO_SMALL;
  528.     
  529.             stMUD.CLOCK  += delta;
  530.                 
  531.             Set_Clock();
  532.             Set_H_Position();
  533.         }
  534.         else                            // delta >= 0, Measure >= Active
  535.         {
  536.             if ((stMUD.CLOCK - 78) < delta)     return ERROR_TOO_BIG;
  537.     
  538.             stMUD.CLOCK -= delta;
  539.                 
  540.             Set_H_Position();
  541.             Set_Clock();
  542.         }   
  543. #else
  544.         // Adjust Clock
  545.         if (usH_End < usIPH_ACT_WID)    // delta < 0, Measure < Active
  546.         {
  547.             if ((228 - stMUD.CLOCK) < delta)    return ERROR_TOO_SMALL;
  548.     
  549.             stMUD.CLOCK += delta;
  550.                 
  551.             Set_Clock();
  552.             Set_H_Position();
  553.         }
  554.         else                            // delta >= 0, Measure >= Active
  555.         {
  556.             if ((stMUD.CLOCK - 28) < delta)     return ERROR_TOO_BIG;
  557.     
  558.             stMUD.CLOCK -= delta;
  559.                 
  560.             Set_H_Position();
  561.             Set_Clock();
  562.         }   
  563. #endif
  564.     }
  565.     while (--count);
  566.     if (0 == count)  return ERROR_TIMEOUT;
  567.     stop    = 0;
  568.     while (1)
  569.     {
  570.         count   = 0x10;     // Phase 4 ~ 28 step 8 (4,12,20,28)
  571.         delta   = 0x00;
  572.         while (1)
  573.         {
  574.             Set_Phase(count);
  575.             
  576.             // Measure usH_Start & usH_End
  577.             ucResult    = Measure_PositionH(NM);
  578.             if (ERROR_SUCCEED != (ucResult & 0x80))
  579.             {
  580.                 if (ERROR_NOTACTIVE == ucResult)
  581.                 {
  582.                     // Input pattern is black/white vertical lines.
  583.                     if (0x70 == count)
  584.                     {
  585.                         Set_Phase(stMUD.PHASE); // Restore phase
  586.                         break;
  587.                     }
  588.                     else
  589.                     {
  590.                         count += 0x20;
  591.                         continue;
  592.                     }
  593.                 }
  594.                 Set_Phase(stMUD.PHASE); // Restore phase
  595.                 return ucResult;
  596.             }
  597.             
  598.             usH_End     = usH_End + 1 - usH_Start;
  599.             ucResult    = (usH_End < usIPH_ACT_WID)
  600.                     ? 0x80 - (unsigned char)(usIPH_ACT_WID - usH_End)
  601.                     : 0x80 + (unsigned char)(usH_End - usIPH_ACT_WID);
  602.             
  603.             if (ucResult > delta)
  604.             {
  605.                 delta   = ucResult;     // Save the biggest width
  606.             }
  607.             if (0x70 == count)
  608.             {
  609.                 Set_Phase(stMUD.PHASE); // Restore phase
  610.                 break;
  611.             }
  612.             count += 0x20;
  613.         }
  614.         if (0x82 < delta)
  615.         {
  616.             stMUD.CLOCK -= 4;
  617.             Set_H_Position();
  618.             Set_Clock();
  619.             stop    = 1;
  620.         }
  621.         else if (0x80 > delta)
  622.         {
  623.             if (stop && (0x7f == delta))    break; 
  624.             stMUD.CLOCK += 4;
  625.             Set_Clock();
  626.             Set_H_Position();
  627.             delta   += 3;
  628.             if (stop)   break;
  629.         }
  630.         else    
  631.             break;
  632.     }
  633. #if (MORE_CLOCK)
  634.     if (0x84 > delta && 0x7c < delta)
  635.     {
  636.         unsigned long   ulTemp0, ulMaxVal;
  637.         unsigned char   ucPhase, ucDetect;
  638.         if (ERROR_SUCCEED != Measure_PositionN(NM))    return ERROR_ABORT;
  639.         // Set auto-tracking window
  640.         Data[0]     = 6;
  641.         Data[1]     = Y_INC;
  642.         Data[2]     = H_BND_STA_L_75;
  643.         Data[3]     = (unsigned char)(usH_Start + MEAS_H_STA_OFFSET - 2);
  644.         Data[4]     = (unsigned char)(usH_End + MEAS_H_END_OFFSET + 1);
  645.         Data[5]     = ((unsigned char)((usH_Start + MEAS_H_STA_OFFSET - 2) >> 4) & 0x70) | ((unsigned char)((usH_End + MEAS_H_END_OFFSET + 1) >> 8) & 0x0f);
  646.         Data[6]     = 0;
  647.         RTDWrite(Data);
  648.         RTDSetByte(DIFF_THRED_7E, 0x50);
  649.         
  650.         ulTemp0     = 0;
  651.         ucDetect    = 0x7b;
  652.         ucResult    = COLORS_GREEN;
  653.         ucPhase     = COLORS_GREEN;
  654.         do
  655.         {
  656.             RTDSetByte(MARGIN_B_7D, ucPhase);
  657.             RTDSetByte(AUTO_ADJ_CTRL_7F, ucDetect);
  658.             Wait_Finish();
  659.             if (ERROR_SUCCEED != Data[0])   return Data[0];
  660.             Read_Auto_Info(1);
  661.             if (ulTemp0 < ((unsigned long *)Data)[1])
  662.             {
  663.                 ulTemp0     = ((unsigned long *)Data)[1];
  664.                 ucResult    = ucPhase;
  665.                 if (0x10000 < ulTemp0)   break;
  666.             }
  667.             if (COLORS_GREEN == ucPhase)
  668.                 ucPhase = COLORS_BLUE;
  669.             else if (COLORS_BLUE == ucPhase)
  670.                 ucPhase = COLORS_RED;
  671.             else
  672.             {
  673.                 if (0x10000 <= ulTemp0 || 0x77 == ucDetect)      break;
  674.                 ulTemp0     = 0;
  675.                 ucDetect    = 0x77;
  676.                 ucPhase     = COLORS_GREEN;
  677.                 ucResult    = COLORS_GREEN;
  678.                 RTDSetByte(DIFF_THRED_7E, 0x70);
  679.             }
  680.         }
  681.         while (1);
  682.         
  683.         // Abort if no suitable color is found
  684.         if (0x8000 > ulTemp0)
  685.         {
  686.             return (28 > stMUD.CLOCK) ? ERROR_TOO_BIG : (228 < stMUD.CLOCK) ? ERROR_TOO_SMALL : ERROR_SUCCEED;
  687.         }
  688.         // Save 4N clock
  689.         stop    = stMUD.CLOCK;
  690.         if (0x81 > delta)
  691.         {
  692.             stMUD.CLOCK = stMUD.CLOCK + 4;
  693.             Set_Clock();
  694.             Set_H_Position();
  695.         }
  696.         ulMaxVal    = 0;
  697.         delta       = 4;
  698.         do
  699.         {
  700.             if (ERROR_SUCCEED != Measure_PositionN(NM))    return ERROR_ABORT;
  701.             // Set auto-tracking window
  702.             Data[0] = 6;
  703.             Data[1] = Y_INC;
  704.             Data[2] = H_BND_STA_L_75;
  705.             Data[3] = (unsigned char)(usH_Start + MEAS_H_STA_OFFSET - 2);
  706.             Data[4] = (unsigned char)(usH_End + MEAS_H_END_OFFSET + 1);
  707.             Data[5] = ((unsigned char)((usH_Start + MEAS_H_STA_OFFSET - 2) >> 4) & 0x70) | ((unsigned char)((usH_End + MEAS_H_END_OFFSET + 1) >> 8) & 0x0f);
  708.             Data[6] = 0;
  709.             RTDWrite(Data);
  710.             
  711.             // Select color for auto-phase tracking
  712.             RTDSetByte(MARGIN_B_7D, ucResult);
  713.             // Set threshold
  714.             RTDSetByte(DIFF_THRED_7E, (0x7b == ucDetect) ? 0x50 : 0x70);
  715.             ulTemp0 = 0;
  716.             ucPhase = 0x00;
  717.             do
  718.             {
  719.                 Set_Phase(ucPhase);
  720.                 RTDSetByte(AUTO_ADJ_CTRL_7F, ucDetect);
  721.                 Wait_Finish();
  722.                 if (ERROR_SUCCEED != Data[0])   return Data[0];
  723.                  Read_Auto_Info(1);
  724.                 if (ulTemp0 < ((unsigned long *)Data)[1])   ulTemp0 = ((unsigned long *)Data)[1];
  725.                 ucPhase += 0x10;
  726.             }
  727.             while (0x80 > ucPhase);
  728.             if (ulMaxVal < ulTemp0)
  729.             {
  730.                 ulMaxVal    = ulTemp0;
  731.                 count       = stMUD.CLOCK;
  732.             }
  733.             if (0x00 == delta)
  734.             {
  735.                 if (128 < stMUD.CLOCK)
  736.                 {
  737.                     // See if default clock is the best
  738.                     delta       = 0xff;
  739.                     stMUD.CLOCK = 128;
  740.                     Set_H_Position();
  741.                     Set_Clock();
  742.                     
  743.                     continue;
  744.                 }
  745.                 else
  746.                     break;
  747.             }
  748.             else if (0xff == delta)
  749.             {
  750.                 break;
  751.             }
  752.             delta       -= 1;
  753.             stMUD.CLOCK -= 1;
  754.             Set_H_Position();
  755.             Set_Clock();
  756.         }
  757.         while (1); 
  758.         if (0x7b == ucDetect)
  759.             stMUD.CLOCK = ((unsigned long)0x38000 < ulMaxVal) ? count : stop;
  760.         else
  761.             stMUD.CLOCK = ((unsigned long)0x48000 < ulMaxVal) ? count : stop;
  762.         Set_Clock();
  763.         Set_H_Position();
  764.         Set_Clock();
  765.     }
  766. #endif
  767. #else
  768.     unsigned char   Result;
  769.     unsigned char   count, delta, stop,start;    
  770.     unsigned long   ulSum,ulCompare;
  771. ulCompare = 0;
  772. ulSum = 0;
  773.         
  774.     ///////////////////////////////
  775.     //  Measure (V) Start & End  //
  776.     ///////////////////////////////
  777.     Result  = Measure_PositionV(NM);
  778.     if (ERROR_SUCCEED != (Result & 0x80))   return Result;
  779.     NM      = NM + 0x10;    // See Min_Noise_Margin(). Horizontal Measure Result is the same when applying (NM + 0x10)
  780.     count   = 10;
  781.     do
  782.     {
  783.    
  784.         ///////////////////////////////
  785.         //  Measure (H) Start & End  //
  786.         ///////////////////////////////
  787.         Result  = Measure_PositionH(NM);
  788.         if (ERROR_SUCCEED != (Result & 0x80))    return Result;
  789.         
  790.         usH_End = usH_End + 1 - usH_Start;
  791.           
  792.         // H_Active Delta
  793.         if (usH_End < usIPH_ACT_WID)
  794.             delta = (usIPH_ACT_WID - usH_End > 0x00ff) ? 0xff : (unsigned char)(usIPH_ACT_WID - usH_End);
  795.         else 
  796.             delta = (usH_End - usIPH_ACT_WID > 0x00ff) ? 0xff : (unsigned char)(usH_End - usIPH_ACT_WID);
  797.         //if (0xc0 < delta)       // The difference is too large to fine-tune.
  798.         if((usIPH_ACT_WID/3) < delta)  //modified 2003/02/25
  799.         {
  800.             return (usH_End < usIPH_ACT_WID) ? ERROR_TOO_SMALL : ERROR_TOO_BIG;
  801.         }
  802.         
  803.         if (1 >= delta)     break;  // 1023,1024,1025,1026,1027
  804.         
  805.         delta   = delta + (delta >> 2);//& 0xfe;  // 4n number
  806. #if(ALIGN_LEFT == CLOCK_ALIGN)
  807.         // Adjust Clock
  808.         if (usH_End < usIPH_ACT_WID)    // delta < 0, Measure < Active
  809.         {
  810.             if ((178 - stMUD.CLOCK) < delta)    return ERROR_TOO_SMALL;
  811.     
  812.             stMUD.CLOCK  += delta;
  813.                 
  814.             Set_Clock();
  815.             Set_H_Position();
  816.         }
  817.         else                            // delta >= 0, Measure >= Active
  818.         {
  819.             if ((stMUD.CLOCK - 78) < delta)     return ERROR_TOO_BIG;
  820.     
  821.             stMUD.CLOCK -= delta;
  822.                 
  823.             Set_H_Position();
  824.             Set_Clock();
  825.         }   
  826. #else
  827.         // Adjust Clock
  828.         if (usH_End < usIPH_ACT_WID)    // delta < 0, Measure < Active
  829.         {
  830.             if ((228 - stMUD.CLOCK) < delta)    return ERROR_TOO_SMALL;
  831.     
  832.             stMUD.CLOCK  += delta;
  833.                 
  834.             Set_Clock();
  835.             Set_H_Position();
  836.         }
  837.         else                            // delta >= 0, Measure >= Active
  838.         {
  839.             if ((stMUD.CLOCK - 28) < delta)     return ERROR_TOO_BIG;
  840.     
  841.             stMUD.CLOCK -= delta;
  842.                 
  843.             Set_H_Position();
  844.             Set_Clock();
  845.         }   
  846.     
  847. #endif
  848.     }
  849.     while (--count);
  850.     if (0 == count)  return ERROR_TIMEOUT;
  851.     stop    = 0;
  852.     while (1)
  853.     {
  854.         count   = 0x10;     // Phase 4 ~ 28 step 4 (4,8,12,16,20,24,28)
  855.         delta   = 0xff;
  856.         while (1)
  857.         {
  858.   
  859.             Set_Phase(count);
  860.             
  861.             // Measure usH_Start & usH_End
  862.             Result  = Measure_PositionH(NM);
  863.             if (ERROR_SUCCEED != (Result & 0x80))
  864.             {
  865.                 if (ERROR_NOTACTIVE == Result)
  866.                 {
  867.                     // Input pattern is black/white vertical lines.
  868.                     if (0x70 == count)
  869.                     {
  870.                         Set_Phase(stMUD.PHASE); // Restore phase
  871.                         break;
  872.                     }
  873.                     else
  874.                     {
  875.                         count += 0x20;
  876.                         continue;
  877.                     }
  878.                 }
  879.                 Set_Phase(stMUD.PHASE); // Restore phase
  880.                 return Result;
  881.             }
  882.             
  883.             usH_End = usH_End + 1 - usH_Start;
  884.             Result  = (usH_End < usIPH_ACT_WID)
  885.                     ? 0x80 - (unsigned char)(usIPH_ACT_WID - usH_End)
  886.                     : 0x80 + (unsigned char)(usH_End - usIPH_ACT_WID);
  887.             
  888.             if (Result < delta)
  889.             {
  890.                 delta   = Result;       // Save the smallest width
  891.             }
  892.             if (0x70 == count)
  893.             {
  894.                 Set_Phase(stMUD.PHASE); // Restore phase
  895.                 break;
  896.             }
  897.             count += 0x10;
  898.         }
  899.         
  900.         if (0x81 < delta)
  901.         {
  902.             stMUD.CLOCK -= 1;
  903.             Set_H_Position();
  904.             Set_Clock();
  905.             stop    = 1;
  906.         }
  907.         else if (0x80 > delta)
  908.         {
  909.             if (stop && (0x7f == delta))    break; 
  910.             stMUD.CLOCK += 1;
  911.             Set_Clock();
  912.             Set_H_Position();
  913.             if (stop)   break;
  914.         }
  915.         else    
  916.             break;
  917.     }
  918.     
  919.     count = stMUD.PHASE;  // Record Current Phase
  920.     start = stMUD.CLOCK ;
  921. if(FindColor() != ERROR_SUCCEED) return ERROR_ABORT;
  922. // Set threshold
  923.     RTDSetByte(DIFF_THRED_7E, 0x30);
  924. ulSum = GetMaxSum(1); //judge if pulse information large enough
  925.     ulCompare = GetMaxSum(0);
  926.     if((ulSum > 460000) || ((ulSum < 460000) && (ulCompare > 2000000)) )
  927. {
  928. ulCompare = 0;    
  929. //    ulSum = 0;//GetMaxSum(0);
  930. //////////////////////////////////////////////
  931. if(0x80 < (start - 2) || 0x80 > start)
  932. {
  933. stMUD.CLOCK = 0x80;
  934. Set_H_Position();
  935. Set_Clock();
  936. ulSum = GetMaxSum(0);
  937. if(ulCompare < ulSum)
  938. {
  939. ulCompare = ulSum;
  940. Result = stMUD.CLOCK;
  941. }
  942. stMUD.CLOCK = start + 1;
  943. }
  944. else
  945. {
  946. stMUD.CLOCK = start;
  947. Set_H_Position();
  948. Set_Clock();
  949. ulSum = GetMaxSum(0);
  950. }
  951. ////////////////////////////////////////////////
  952. while(1)
  953. {
  954. if(ulCompare < ulSum)
  955. {
  956. ulCompare = ulSum;
  957. Result = stMUD.CLOCK;
  958. }
  959. if(stMUD.CLOCK == start - 2)
  960. break;    
  961. stMUD.CLOCK -= 1;
  962. Set_Clock();
  963. Set_H_Position();
  964. ulSum = GetMaxSum(0);        
  965. }
  966. stMUD.CLOCK = Result;
  967. stMUD.PHASE = count;
  968. Set_Clock();
  969. Set_H_Position();
  970. Set_Phase(stMUD.PHASE);
  971.     }  
  972. #endif
  973.     return (28 > stMUD.CLOCK) ? ERROR_TOO_BIG : (228 < stMUD.CLOCK) ? ERROR_TOO_SMALL : ERROR_SUCCEED;
  974. }
  975. //------------------------------------------------------------------//
  976. //                          Auto Position                           //
  977. //------------------------------------------------------------------//
  978. unsigned char Auto_Position(void)
  979. {
  980.     unsigned char   Result, Curr_PosH, Curr_PosV;
  981.     bAutoInProgress = 1;
  982.     Curr_PosH   = stMUD.H_POSITION;     // Save current stMUD.H_POSITION
  983.     Curr_PosV   = stMUD.V_POSITION;     // Save current stMUD.V_POSITION
  984.     if (ucV_Max_Margin < stMUD.V_POSITION)
  985.     {
  986.         stMUD.V_POSITION    = ucV_Max_Margin;
  987.         Set_V_Position();
  988.     }
  989.     RTDCodeW(ADC_DEFAULT);
  990.     ///////////////////////////////
  991.     //   Measure  NOISE_MARGIN   //
  992.     ///////////////////////////////
  993.     Result  = Min_Noise_Margin();
  994.     if (ERROR_SUCCEED == (Result & 0x80))
  995.     {   
  996.         ///////////////////////////////
  997.         //    Adjust (H/V)Position   //
  998.         ///////////////////////////////
  999.         Result  = Auto_Position_Do(Data[0]);    // Noise margin returned by Min_Noise_Margin() is saved in Data[0];
  1000.     }
  1001.     if (ERROR_SUCCEED == (Result & 0x80))
  1002.     {
  1003.         Save_MUD(ucMode_Curr);
  1004.     }
  1005.     else
  1006.     {
  1007.         stMUD.H_POSITION    = Curr_PosH;
  1008.         stMUD.V_POSITION    = Curr_PosV;
  1009.         Set_H_Position();
  1010.         Set_V_Position();
  1011.     }
  1012.     
  1013.     // Restore ADC Gain/Offset
  1014.     SetADC_GainOffset();
  1015.     bAutoInProgress = 0;
  1016.     return Result;
  1017. }
  1018. //------------------------------------------------------------------//
  1019. // Return Message => ERROR_SUCCESS   : Success                      //
  1020. //                   ERROR_SUCCESS_1 : Vertical Start > Max         //
  1021. //                   ERROR_SUCCESS_2 : Vertical Start < Min         //
  1022. //                   ERROR_SUCCESS_4 : Vertical Start/End Fail      //
  1023. //                   ERROR_SUCCESS_8 : Horizontal Start > Max       //
  1024. //                   ERROR_SUCCESS_16: Horizontal Start < Min       //
  1025. //                   ERROR_SUCCESS_32: Horizontal Start/End Fail    //
  1026. //                   ERROR_INPUT     : 1. IVS or IHS changed        //
  1027. //                                     2. underflow or overflow     //
  1028. //                   ERROR_TIMEOUT   : Measure Time_Out             //
  1029. //                   ERROR_NOTACTIVE : No Avtive Image              //
  1030. //------------------------------------------------------------------//
  1031. unsigned char Auto_Position_Do(unsigned char NM)
  1032. {
  1033.     unsigned char   Result;//,ucTemp,ucTemp1;
  1034. // unsigned int    usTemp;
  1035. /*
  1036.     
  1037. ///////////////////////////////////////////////////////////
  1038. stMUD.H_POSITION = 128;
  1039.     
  1040. if(128 >= stMUD.H_POSITION)
  1041.     {
  1042.     ucTemp = 128 - stMUD.H_POSITION;
  1043.     
  1044. if(stMUD.CLOCK > 128)
  1045.    ucTemp1 = 128;
  1046. else
  1047.    ucTemp1 = stMUD.CLOCK;
  1048. ucH_Min_Margin = 128 - ucTemp - (64 - (ucTemp1 >> 1));
  1049. usIPH_ACT_STA = usIPH_ACT_STA + 50 - ucTemp - (64 - (ucTemp1 >> 1));
  1050. usTemp = usIPH_ACT_STA;
  1051. Set_H_Position();
  1052.     }
  1053. ///////////////////////////////////////////////////////////////////    
  1054. */
  1055.     Result      = Measure_PositionN(NM);
  1056.     if (ERROR_SUCCEED != (Result & 0x80))   return Result;
  1057.     Result  = ERROR_SUCCEED;
  1058.     /////////////////////////////////
  1059.     // Calculate Vertical Position //
  1060.     /////////////////////////////////
  1061.     NM  = 1;
  1062.     while (1)
  1063.     {
  1064.         if ((usIPV_ACT_STA + ucV_Max_Margin - 128) >= usVer_Start)
  1065.         {
  1066.             if ((usIPV_ACT_STA + ucV_Min_Margin - 128) <= usVer_Start)
  1067.             {
  1068.                 stMUD.V_POSITION = (usVer_Start + 128) - usIPV_ACT_STA;
  1069.                 Set_V_Position();
  1070.                 break;  // Success
  1071.             }
  1072.             else
  1073.                 Result  |= ERROR_SUCCESS_2;
  1074.         }
  1075.         else
  1076.             Result  |= ERROR_SUCCESS_1;
  1077.         // If we can't align upper bound, we try to align lower bound.
  1078.         if (NM && usVer_End > usIPV_ACT_LEN)
  1079.         {
  1080.             usVer_Start = usVer_End - usIPV_ACT_LEN + 1;
  1081.             NM          = 0;
  1082.         }
  1083.         else
  1084.         {
  1085.             Result  |= ERROR_SUCCESS_4;
  1086.             break;
  1087.         }
  1088.     }
  1089.     
  1090.     ///////////////////////////////////
  1091.     // Calculate Horizontal Position //
  1092.     ///////////////////////////////////
  1093.     NM  = 1;
  1094.     while (1)
  1095.     {
  1096. #if(ALIGN_LEFT == CLOCK_ALIGN)
  1097.         if ((usIPH_ACT_STA + (stMUD.CLOCK >> 2) + ucH_Max_Margin - 32 - 128) >= usH_Start)
  1098.         {
  1099. //if(ucH_Min_Margin  == (128 - 10))
  1100.             if(ucH_Min_Margin  <= 128 )
  1101.   ((unsigned int*)Data)[0] = usH_Start + 128 - stMUD.H_POSITION + 50;//((unsigned int*)Data)[0] = usH_Start + ucTemp + 100;//((unsigned int*)Data)[0] = usH_Start + 10;
  1102. else
  1103.   ((unsigned int*)Data)[0] = usH_Start;// + (stMUD.H_POSITION - 128) + 10;
  1104.             //if ((usIPH_ACT_STA + (stMUD.CLOCK >> 1) + ucH_Min_Margin - 64 - 128) <= (usH_Start + 50))
  1105. if ((usIPH_ACT_STA + (stMUD.CLOCK >> 2) + ucH_Min_Margin - 32 - 128) <= ((unsigned int*)Data)[0])
  1106.             {
  1107.                 //usH_Start is the actual distance from Hsync to active image
  1108.             stMUD.H_POSITION    = usH_Start + 128 + 32 - usIPH_ACT_STA - (stMUD.CLOCK >> 2);
  1109. Set_H_Position();
  1110.                 
  1111.                 break;  // Success
  1112.             }
  1113.             else
  1114.                 Result  |= ERROR_SUCCESS_16;
  1115.         }
  1116.         else
  1117.             Result  |= ERROR_SUCCESS_8;
  1118. #else
  1119.         if ((usIPH_ACT_STA + (stMUD.CLOCK >> 1) + ucH_Max_Margin - 64 - 128) >= usH_Start)
  1120.         {
  1121. //if(ucH_Min_Margin  == (128 - 10))
  1122.             if(ucH_Min_Margin  <= 128 )
  1123.   ((unsigned int*)Data)[0] = usH_Start + 128 - stMUD.H_POSITION + 100;//((unsigned int*)Data)[0] = usH_Start + ucTemp + 100;//((unsigned int*)Data)[0] = usH_Start + 10;
  1124. else
  1125.   ((unsigned int*)Data)[0] = usH_Start;// + (stMUD.H_POSITION - 128) + 10;
  1126.             //if ((usIPH_ACT_STA + (stMUD.CLOCK >> 1) + ucH_Min_Margin - 64 - 128) <= (usH_Start + 50))
  1127. if ((usIPH_ACT_STA + (stMUD.CLOCK >> 1) + ucH_Min_Margin - 64 - 128) <= ((unsigned int*)Data)[0])
  1128.             {
  1129.                 //usH_Start is the actual distance from Hsync to active image
  1130.             stMUD.H_POSITION    = usH_Start + 128 + 64 - usIPH_ACT_STA - (stMUD.CLOCK >> 1);
  1131. Set_H_Position();
  1132.                 
  1133.                 break;  // Success
  1134.             }
  1135.             else
  1136.                 Result  |= ERROR_SUCCESS_16;
  1137.         }
  1138.         else
  1139.             Result  |= ERROR_SUCCESS_8;
  1140. #endif
  1141.         // If we can't align upper bound, we try to align lower bound.
  1142.         if (NM && usH_End > usIPH_ACT_WID)
  1143.         {
  1144.             usH_Start   = usH_End - usIPH_ACT_WID + 1;
  1145.             NM          = 0;
  1146.         }
  1147.         else
  1148.         {
  1149.             Result  |= ERROR_SUCCESS_32;
  1150.             break;
  1151.         }
  1152.     }
  1153. /*
  1154. //////////////////////////////////////////////////////////////////////////////
  1155.     if(ucH_Min_Margin == (128 - ucTemp))
  1156. {
  1157.         if(usTemp != usIPH_ACT_STA)
  1158. {
  1159.    stMUD.H_POSITION = stMUD.H_POSITION - (usTemp - usIPH_ACT_STA);
  1160.    usIPH_ACT_STA = usTemp - 50 + ucTemp + (64 - (ucTemp1 >> 1));
  1161. }
  1162. else
  1163.     usIPH_ACT_STA   = usIPH_ACT_STA - 50 + ucTemp + (64 - (ucTemp1 >> 1));
  1164. ucH_Min_Margin  = 128 - 50;   
  1165. Set_H_Position();
  1166. }
  1167. ////////////////////////////////////////////////////////////////////////////////
  1168. */
  1169.     return Result;
  1170. }
  1171. unsigned char Min_Noise_Margin(void)
  1172. {
  1173.     unsigned char   Result, Noise;
  1174.     unsigned int    Curr_StartH, Curr_EndH;
  1175.     Result  = Measure_PositionV(VERTICAL_MARGIN);
  1176.     
  1177.     if (ERROR_SUCCEED != (Result & 0x80))   return Result;
  1178.     
  1179.     if (0 == usVer_Start)
  1180.     {
  1181.         Result  = Measure_PositionV(VERTICAL_MARGIN + 0x20);
  1182.         if (ERROR_SUCCEED != (Result & 0x80))   return Result;
  1183.     }
  1184.     
  1185.     Noise   = 0x00;
  1186.     Result  = Measure_PositionH(Noise);
  1187.     if (ERROR_SUCCEED != (Result & 0x80))   return Result;
  1188.         
  1189.     Curr_StartH = usH_Start;    // Save H start position at noise margin = 0
  1190.     Curr_EndH   = usH_End;      // Save H end position at noise margin = 0
  1191.     do
  1192.     {
  1193.         Noise   = Noise + 0x10;
  1194.         Result  = Measure_PositionH(Noise);
  1195.         if (ERROR_SUCCEED != (Result & 0x80))   return Result;
  1196.     
  1197.         if (Curr_StartH >= usH_Start)
  1198.         {
  1199.             Curr_StartH = usH_Start;
  1200.         }
  1201.         else if (0x08 < (usH_Start - Curr_StartH))
  1202.         {
  1203.             break;  // A large gap of H start position is found.
  1204.         }
  1205.     }
  1206.     while (0x90 > Noise);
  1207.     if (0x80 < Noise)   return ERROR_NOISE_TOO_BIG;      
  1208.     while (1)
  1209.     {   
  1210.         Curr_StartH = usH_Start;
  1211.         Curr_EndH   = usH_End;
  1212.         Result  = Measure_PositionH(Noise + 0x28);
  1213.         
  1214.         if (ERROR_SUCCEED != (Result & 0x80))   return Result;
  1215.         if ((Curr_EndH - Curr_StartH) == (usH_End - usH_Start) || (Curr_EndH - Curr_StartH) >= (usH_End - usH_Start + 3))
  1216.         {
  1217.             break;  // We got noise margin with stable horizontal start/end position.
  1218.         }
  1219.         
  1220.         if (0xa0 <= Noise)
  1221.         {
  1222.             break;  // No stable horizontal start/end position are found.
  1223.         }
  1224.         Noise   = Noise + 0x10;        
  1225.         Result  = Measure_PositionH(Noise);
  1226.         if (ERROR_SUCCEED != (Result & 0x80))   return Result;
  1227.     };
  1228.     Data[0] = Noise + 0x10;
  1229.     return ERROR_SUCCEED;
  1230. }
  1231. unsigned char Auto_Phase(void)
  1232. {
  1233.     unsigned char   Result, Curr_PosV;
  1234.     bAutoInProgress = 1;
  1235.     Curr_PosV   = stMUD.V_POSITION;     // Save current stMUD.V_POSITION
  1236.     if (ucV_Max_Margin < stMUD.V_POSITION)
  1237.     {
  1238.         stMUD.V_POSITION    = ucV_Max_Margin;
  1239.         Set_V_Position();
  1240.     }
  1241.     // Set ADC to default
  1242.     RTDCodeW(ADC_DEFAULT);
  1243.     ///////////////////////////////
  1244.     //   Measure  NOISE_MARGIN   //
  1245.     ///////////////////////////////
  1246.     Result  = Min_Noise_Margin();
  1247.     if (ERROR_SUCCEED == (Result & 0x80))
  1248.     {   
  1249.         Result      = Auto_Phase_Do(Data[0]);   // Noise margin returned by Min_Noise_Margin() is saved in Data[0];
  1250.     }
  1251.     if (ERROR_SUCCEED != (Result & 0x80))
  1252.     {
  1253.         // Restore Phase
  1254.         Set_Phase(stMUD.PHASE);
  1255.     }
  1256.     else
  1257.     {
  1258.         Save_MUD(ucMode_Curr);
  1259.     }
  1260.     // Restore ADC Gain/Offset
  1261.     SetADC_GainOffset();
  1262.     // Restore vertical position
  1263.     if (Curr_PosV != stMUD.V_POSITION)
  1264.     {
  1265.         stMUD.V_POSITION    = Curr_PosV;
  1266.         Set_V_Position();
  1267.     }
  1268.     bAutoInProgress = 0;
  1269.     return Result;
  1270. }
  1271. unsigned char Auto_Phase_Do(unsigned char NM)
  1272. {
  1273.     unsigned char idata ucDetect, ucPhase, ucResult;
  1274.     unsigned long idata ulTemp0, ulTemp1, ulTemp2;
  1275. /*
  1276.     //reduce the bandwidth of ADC to prevent overshoot
  1277.     if(ucMode_Curr <= MODE_1280x1024x75HZ)
  1278.        RTDSetByte(ADC_REG_TEST_E9, 0x08);
  1279.     else if(ucMode_Curr < MODE_1024x0768x70HZ)
  1280.        RTDSetByte(ADC_REG_TEST_E9, 0x00);
  1281.     else
  1282.        RTDSetByte(ADC_REG_TEST_E9, 0x10);
  1283. */
  1284.     if (ERROR_SUCCEED != Measure_PositionN(NM))    return ERROR_ABORT;
  1285.     // Set auto-tracking window
  1286.     Data[0]     = 6;
  1287.     Data[1]     = Y_INC;
  1288.     Data[2]     = H_BND_STA_L_75;
  1289.     Data[3]     = (unsigned char)(usH_Start + MEAS_H_STA_OFFSET - 2);
  1290.     Data[4]     = (unsigned char)(usH_End + MEAS_H_END_OFFSET + 1);
  1291.     Data[5]     = ((unsigned char)((usH_Start + MEAS_H_STA_OFFSET - 2) >> 4) & 0x70) | ((unsigned char)((usH_End + MEAS_H_END_OFFSET + 1) >> 8) & 0x0f);
  1292.     Data[6]     = 0;
  1293.     RTDWrite(Data);
  1294.     RTDSetByte(DIFF_THRED_7E, 0x30);
  1295.     ulTemp0     = 0;
  1296.     ucDetect    = 0x7b;
  1297.     do
  1298.     {
  1299.         ucResult    = COLORS_GREEN;
  1300.         ucPhase     = COLORS_GREEN;
  1301.         do
  1302.         {
  1303.             RTDSetByte(MARGIN_B_7D, ucPhase);
  1304.             RTDSetByte(AUTO_ADJ_CTRL_7F, ucDetect);
  1305.             Wait_Finish();
  1306.             if (ERROR_SUCCEED != Data[0])   return Data[0];
  1307.             Read_Auto_Info(1);
  1308.             if (ulTemp0 < ((unsigned long *)Data)[1])
  1309.             {
  1310.                 ulTemp0     = ((unsigned long *)Data)[1];
  1311.                 ucResult    = ucPhase;
  1312.                 if (0x8000 < ulTemp0)   break;
  1313.             }
  1314.             if (COLORS_GREEN == ucPhase)
  1315.                 ucPhase = COLORS_BLUE;
  1316.             else if (COLORS_BLUE == ucPhase)
  1317.                 ucPhase = COLORS_RED;
  1318.             else
  1319.                 break;
  1320.         }
  1321.         while (1);
  1322.         if (0 != ulTemp0 || 0x7b != ucDetect)   break;
  1323.         ucDetect    = 0x77;
  1324.     }
  1325.     while (1);
  1326.     // Abort if no suitable color is found
  1327.     if (0 == ulTemp0)   return ERROR_NOTACTIVE;
  1328.    // NM = COLORS_GREEN;
  1329.     // Select color for auto-phase tracking
  1330.     RTDSetByte(MARGIN_B_7D, NM | ucResult);
  1331. #if(1)
  1332.     //NM = 136;
  1333. NM = 100;
  1334. #else
  1335.     // Find suitable threshold
  1336.     // We use phase 8 and 24 to find out it
  1337.     ucPhase = 0x20;
  1338.     Set_Phase(ucPhase);
  1339.     ucResult    = 0x28;
  1340.     NM          = 0x00;
  1341.     do
  1342.     {
  1343.         do
  1344.         {
  1345.             ucResult    += 0x20;
  1346.             RTDSetByte(DIFF_THRED_7E, ucResult);
  1347.             RTDSetByte(AUTO_ADJ_CTRL_7F, ucDetect);
  1348.             Wait_Finish();
  1349.             if (ERROR_SUCCEED != Data[0])   return Data[0];
  1350.             Read_Auto_Info(1);
  1351.             if ((unsigned long)0x1000 > ((unsigned long *)Data)[1])
  1352.             {
  1353.                 ucResult    -= 0x20;
  1354.                 break;
  1355.             }
  1356.         }
  1357.         while (0x88 > ucResult);
  1358.         if (0x88 == ucResult)
  1359.         {
  1360.             NM  = ucResult;
  1361.             break;
  1362.         }
  1363.         else
  1364.         {
  1365.             if (0x20 == ucPhase)
  1366.             {
  1367.                 NM  = ucResult;
  1368.                 ucPhase = 0x60;
  1369.                 Set_Phase(ucPhase);
  1370.             }
  1371.             else
  1372.             {
  1373.                 if (NM < ucResult)      NM  = ucResult;
  1374.                 
  1375.                 break;
  1376.             }
  1377.         }
  1378.     }
  1379.     while (1);
  1380.     // Set threshold
  1381.     if(NM < 136) NM = 136;
  1382. #endif
  1383.     RTDSetByte(DIFF_THRED_7E, NM);
  1384. #if(1)  //FAST_AUTO method 1
  1385.         // Set phase 30
  1386. Set_Phase(0x78);
  1387. Delay_Xms(1);
  1388. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1389. Wait_Finish();
  1390. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1391. Read_Auto_Info(1);
  1392.       
  1393. ulTemp1     = ((unsigned long *)Data)[1];
  1394. #if(HARDWARE_AUTO)
  1395.         ulTemp2     = ulTemp1;
  1396. ulTemp0     = 0;
  1397.         RTDSetByte(HW_AUTO_PHASE_9E,0x05);  //Step 2 auto phase
  1398. //Wait_For_Event(EVENT_IVS);
  1399. Wait_For_IVS();
  1400. RTDSetByte(AUTO_ADJ_CTRL_7F,0x77); // Auto start
  1401. //Wait_For_Event(EVENT_IVS);
  1402. Wait_For_IVS();
  1403.         for(ucDetect = 0;ucDetect < 16; ucDetect++)
  1404.         {
  1405.                //Wait_For_Event(EVENT_IVS);
  1406.    Wait_For_IVS();
  1407.                Read_Auto_Info(3);
  1408.             /*   
  1409.    Data[0]     = 7;
  1410.                Data[1]     = ADDR_EROM1;
  1411.                Data[2]     = 0x40 + (ucDetect << 2);
  1412.                Data[3]     = (unsigned char)(((unsigned long *)Data)[3] >> 12);
  1413.                Data[4]     = (unsigned char)(((unsigned long *)Data)[3] >> 8);
  1414.                Data[5]     = (unsigned char)(((unsigned long *)Data)[3] >> 4);
  1415.                Data[6]     = 0x00;
  1416.                
  1417.    I2CWrite(Data);
  1418.   */ 
  1419.               if(ulTemp0 < ((unsigned long *)Data)[3])
  1420.               {
  1421.                    ulTemp0   = ((unsigned long *)Data)[3] & 0xffffff00; //Store the SOD of phase(n)
  1422.    ulTemp1   = ulTemp2;                                 //Store the SOD of phase(n-2)
  1423.    ucResult  = ucDetect << 3;                           //Save the phase
  1424.               }
  1425.               ulTemp2 = ((unsigned long*)Data)[3] & 0xffffff00;
  1426.   
  1427.         }
  1428. Wait_Finish();
  1429. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1430.         RTDSetByte(HW_AUTO_PHASE_9E,0x00);  //Switch back to software auto phase
  1431. #else
  1432. // Set phase 0
  1433. Set_Phase(0x00);
  1434. Delay_Xms(1);
  1435. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1436. Wait_Finish();
  1437. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1438. Read_Auto_Info(1);
  1439.       
  1440. ulTemp0     = ((unsigned long *)Data)[1];
  1441. ulTemp2     = ulTemp0;
  1442. ucResult    = 0x00;
  1443. ucPhase     = 0x08;//2 step rought scan
  1444. do
  1445. {
  1446. Set_Phase(ucPhase);
  1447. Delay_Xms(1);
  1448. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1449. Wait_Finish();
  1450. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1451.             Read_Auto_Info(3);
  1452.        
  1453. // ((unsigned long *)Data)[0]  = ulTemp1 + ulTemp2 + ((unsigned long *)Data)[1];
  1454. if (ulTemp0 < ((unsigned long *)Data)[3])
  1455. {
  1456. ulTemp0     = ((unsigned long *)Data)[3];  //Save the SOD of phase(n)
  1457. ulTemp1     = ulTemp2;                     //Save the SOD of phase(n-2)
  1458. ucResult    = ucPhase;
  1459. }
  1460. ulTemp2 = ((unsigned long *)Data)[3];
  1461. ucPhase = ucPhase + 0x08;
  1462. }
  1463. while (0x78 != ucPhase);
  1464. if((ucResult == 0x00) && (ulTemp1 > ulTemp2))//Compare the value of phase 28 & phase 30
  1465. {
  1466.      ucResult = 0x78;  //The maximum equal to phase 30
  1467.  ulTemp0 = ulTemp1; //Save the value of phase 30
  1468.  ulTemp1 = ulTemp2; //Save the value of phase 28
  1469. }
  1470. #endif
  1471.         ucPhase = ucResult == 0x00 ? 0x7c : (ucResult - 0x04 );
  1472.         ulTemp2 = 0;
  1473.         ucDetect = 2;
  1474.         Set_Phase(ucPhase); //set Phase(n-1)
  1475. Delay_Xms(1);
  1476. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1477. Wait_Finish();
  1478. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1479.         Read_Auto_Info(1);
  1480.         ulTemp2 = ((unsigned long*)Data)[1];   //Save the SOD of  phase(n-1)
  1481.         ((unsigned long*)Data)[0] 
  1482. = ulTemp1 + ulTemp2 + ulTemp0 
  1483.         -((ulTemp1 > ulTemp2 ? ulTemp1 - ulTemp2 : ulTemp2 - ulTemp1)/2)
  1484. -((ulTemp2 > ulTemp0 ? ulTemp2 - ulTemp0 : ulTemp0 - ulTemp2)/2);
  1485. ulTemp1 = ((unsigned long*)Data)[0];
  1486. ucPhase = ucResult; 
  1487.         ucResult = ucResult == 0x00 ? 0x7c : ucResult - 0x04;
  1488.         do //detail scan by one step from phase(n-2) ~ pnase (n+2)
  1489.         {
  1490.            ucPhase = (ucPhase == 0x7c) ? 0x00 : ucPhase + 0x04;
  1491.            Set_Phase(ucPhase);
  1492.        Delay_Xms(1);
  1493.    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1494.            Wait_Finish();
  1495.    if (ERROR_SUCCEED != Data[0])   return Data[0];
  1496.            Read_Auto_Info(3);
  1497.           ((unsigned long *)Data)[0]  
  1498.            = ulTemp2 + ulTemp0 + ((unsigned long *)Data)[3]
  1499.            - ((ulTemp0 > ulTemp2 ? ulTemp0 - ulTemp2 : ulTemp2 - ulTemp0) / 2)
  1500.            - ((ulTemp0 > ((unsigned long *)Data)[3] ? ulTemp0 - ((unsigned long *)Data)[3] : ((unsigned long *)Data)[3] - ulTemp0) / 2);
  1501.            if(((unsigned long*)Data)[0] > ulTemp1)
  1502.            {
  1503.                ulTemp1 = ((unsigned long*)Data)[0];
  1504.                ucResult = (ucPhase == 0x00) ? 0x7c : ucPhase - 0x04;
  1505.            }
  1506.            ucDetect -= 1;
  1507.            
  1508.            ulTemp2 = ulTemp0;
  1509.            ulTemp0 = ((unsigned long *)Data)[3];
  1510.         }while(ucDetect);
  1511. #else   //FAST AUTO method 2
  1512. // Set phase 30
  1513. Set_Phase(0x78);
  1514. Delay_Xms(1);
  1515. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1516. Wait_Finish();
  1517. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1518. Read_Auto_Info(1);
  1519.       
  1520. ulTemp2     = ((unsigned long *)Data)[1];
  1521. // Set phase 0
  1522. //Set_Phase(0x00 | ucDetect);
  1523.         Set_Phase(0x00);
  1524. Delay_Xms(1);
  1525. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1526. Wait_Finish();
  1527. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1528. Read_Auto_Info(2);
  1529.        
  1530. ulTemp1 = ((unsigned long *)Data)[2];
  1531. ulTemp0     = 0;
  1532. ucResult    = 0x08;
  1533. ucPhase     = 0x08;//2 step rought scan
  1534. do
  1535. {
  1536. Set_Phase(ucPhase);
  1537. Delay_Xms(1);
  1538. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1539. Wait_Finish();
  1540. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1541.             Read_Auto_Info(3);
  1542.        
  1543. // ((unsigned long *)Data)[0]  = ulTemp1 + ulTemp2 + ((unsigned long *)Data)[1];
  1544.            ((unsigned long *)Data)[0]  
  1545.    = ulTemp2 + ulTemp1 + ((unsigned long *)Data)[3]
  1546.             - ((ulTemp1 > ulTemp2 ? ulTemp1 - ulTemp2 : ulTemp2 - ulTemp1) / 2)
  1547.             - ((ulTemp1 > ((unsigned long *)Data)[3] ? ulTemp1 - ((unsigned long *)Data)[3] : ((unsigned long *)Data)[3] - ulTemp1) / 2);
  1548. if (ulTemp0 < ((unsigned long *)Data)[0])
  1549. {
  1550. ulTemp0     = ((unsigned long *)Data)[0];
  1551. ucResult    = ucPhase - 0x08;
  1552. }
  1553. ulTemp2 = ulTemp1;
  1554. ulTemp1 = ((unsigned long *)Data)[3];
  1555. ucPhase = ucPhase + 0x08;
  1556. }
  1557. while (0x78 != ucPhase);
  1558. // ((unsigned long *)Data)[0]  = ulTemp1 + ulTemp2 + ((unsigned long *)Data)[3];
  1559. // ((unsigned long *)Data)[1]  = ((unsigned long *)Data)[3] + ulTemp1 + ((unsigned long *)Data)[2];
  1560.        ((unsigned long *)Data)[0]//phase26+phase28+phase30
  1561.         = ulTemp2 + ulTemp1 + ((unsigned long *)Data)[1]
  1562.         - ((ulTemp1 > ulTemp2 ? ulTemp1 - ulTemp2 : ulTemp2 - ulTemp1) / 2)
  1563.         - ((ulTemp1 > ((unsigned long *)Data)[1] ? ulTemp1 - ((unsigned long *)Data)[1] : ((unsigned long *)Data)[1] - ulTemp1) / 2);
  1564.        
  1565.        ((unsigned long *)Data)[3]//phase28+phase30+phase0
  1566.         = ulTemp1 + ((unsigned long *)Data)[1] + ((unsigned long *)Data)[2]
  1567.         - ((((unsigned long *)Data)[1] > ulTemp1 ? ((unsigned long *)Data)[1] - ulTemp1 : ulTemp1 - ((unsigned long *)Data)[1]) / 2)
  1568.         - ((((unsigned long *)Data)[1] > ((unsigned long *)Data)[2] ? ((unsigned long *)Data)[1] - ((unsigned long *)Data)[2] : ((unsigned long *)Data)[2] - ((unsigned long *)Data)[1]) / 2);
  1569. if (ulTemp0 < ((unsigned long *)Data)[0])
  1570. {
  1571. ulTemp0     = ((unsigned long *)Data)[0];
  1572. ucResult    = 0x70;  //ucResult = phase28
  1573. }
  1574. if (ulTemp0 < ((unsigned long *)Data)[3])
  1575. {
  1576. ulTemp0     = ((unsigned long *)Data)[3];
  1577. ucResult    = 0x78;  //ucResult = phase30
  1578. }
  1579.         ucPhase = ucResult >= 0x08 ? (ucResult - 0x08) : (ucResult + 0x80 - 0x08);
  1580.         ulTemp0 = 0;
  1581.         ulTemp1 = 0;
  1582.         ulTemp2 = 0;
  1583.         ucDetect = 3;
  1584.         Set_Phase(ucPhase); //set Phase(n-2)
  1585. Delay_Xms(1);
  1586. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1587. Wait_Finish();
  1588. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1589.         Read_Auto_Info(1);
  1590.         ulTemp1 = ((unsigned long*)Data)[1];
  1591.         ucPhase = (ucPhase == 0x7c) ? 0x00 : ucPhase + 0x04; //set Phase(n-1)
  1592.         Set_Phase(ucPhase);
  1593. Delay_Xms(1);
  1594. RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1595. Wait_Finish();
  1596. if (ERROR_SUCCEED != Data[0])   return Data[0];
  1597.         Read_Auto_Info(2);
  1598.         ulTemp2 = ((unsigned long*)Data)[2];
  1599.         do //detail scan by one step from phase(n-2) ~ pnase (n+2)
  1600.         {
  1601.            ucPhase = (ucPhase == 0x7c) ? 0x00 : ucPhase + 0x04;
  1602.            Set_Phase(ucPhase);
  1603.        Delay_Xms(1);
  1604.    RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
  1605.            Wait_Finish();
  1606.    if (ERROR_SUCCEED != Data[0])   return Data[0];
  1607.            Read_Auto_Info(3);
  1608.           ((unsigned long *)Data)[0]  
  1609.            = ulTemp1 + ulTemp2 + ((unsigned long *)Data)[3]
  1610.            - ((ulTemp1 > ulTemp2 ? ulTemp1 - ulTemp2 : ulTemp2 - ulTemp1) / 2)
  1611.            - ((ulTemp2 > ((unsigned long *)Data)[3] ? ulTemp2 - ((unsigned long *)Data)[3] : ((unsigned long *)Data)[3] - ulTemp2) / 2);
  1612.            if(((unsigned long*)Data)[0] > ulTemp0)
  1613.            {
  1614.                ulTemp0 = ((unsigned long*)Data)[0];
  1615.                ucResult = (ucPhase == 0x00) ? 0x7c : ucPhase - 0x04;
  1616.            }
  1617.            ucDetect -= 1;
  1618.            
  1619.            ulTemp1 = ulTemp2;
  1620.            ulTemp2 = ((unsigned long *)Data)[3];
  1621.         }while(ucDetect);
  1622.         
  1623. //        ucDebug_Value1 = ucResult;
  1624. #endif        
  1625. stMUD.PHASE = ucResult;
  1626. Set_Phase(stMUD.PHASE);
  1627. /*
  1628.     //restore the bandwidth setup of ADC
  1629.     if(ucMode_Curr < MODE_1024x0768x70HZ)
  1630.      RTDSetByte(ADC_REG_TEST_E9, 0x08);
  1631.     else 
  1632.         RTDSetByte(ADC_REG_TEST_E9, 0x10);
  1633. */
  1634.    
  1635.     return ERROR_SUCCEED;
  1636. }
  1637. unsigned char Auto_Config(void)
  1638. {
  1639.     unsigned char   Result, Noise, Curr_PosH, Curr_PosV, Curr_Clock, Curr_Phase;
  1640.     unsigned char ucTemp1;
  1641. unsigned int usTemp;
  1642.     bAutoInProgress = 1;
  1643.     
  1644.     Curr_PosH   = stMUD.H_POSITION;     // Save current stMUD.H_POSITION
  1645.     Curr_PosV   = stMUD.V_POSITION;     // Save current stMUD.V_POSITION
  1646.     Curr_Clock  = stMUD.CLOCK;          // Save current stMUD.CLOCK
  1647.     Curr_Phase  = stMUD.PHASE;          // Save current stMUD.PHASE
  1648.     if (ucV_Max_Margin < stMUD.V_POSITION)
  1649.     {
  1650.         stMUD.V_POSITION    = ucV_Max_Margin - 1;
  1651.         Set_V_Position();
  1652.     }
  1653. //   RTDCodeW(ADC_DEFAULT);
  1654. /////////original formula////////////////////////////////////////////
  1655.     //Set the H Position center(without IHS_Delay)
  1656. /*
  1657.     stMUD.H_POSITION = 128; 
  1658.     
  1659. if(128 >= stMUD.H_POSITION)
  1660.     {
  1661.     ucTemp = 128 - stMUD.H_POSITION; 
  1662.     
  1663. if(stMUD.CLOCK > 128)
  1664.    ucTemp1 = 128;
  1665. else
  1666.    ucTemp1 = stMUD.CLOCK;
  1667.     //According to the H_Position adjust the IHS pre-delay
  1668. ucH_Min_Margin = 128 - ucTemp - (64 - (ucTemp1 >> 1));
  1669.     //Return the IPH_ACT_STA to the original one first,and compensate the IHS pre-delay
  1670.     //The h position must be equal after change the IHS delay and IPH_ACT_STA
  1671. usIPH_ACT_STA = usIPH_ACT_STA + 50 - ucTemp - (64 - (ucTemp1 >> 1));
  1672. usTemp = usIPH_ACT_STA;
  1673. Set_H_Position();
  1674.     }
  1675. */
  1676. ///////////////////////////////////////////////////////////////////    
  1677. ////////////////////////////////////////////////////////////////////
  1678.     //Set the H Position center(without IHS_Delay)
  1679.     stMUD.H_POSITION = 128; 
  1680.     
  1681.     //ucTemp = 128 - stMUD.H_POSITION; 
  1682.     
  1683. if(stMUD.CLOCK > 128)
  1684.    ucTemp1 = 128;
  1685. else
  1686.    ucTemp1 = stMUD.CLOCK;
  1687.     //According to the H_Position adjust the IHS pre-delay
  1688. ucH_Min_Margin = 128 - (64 - (ucTemp1 >> 1));
  1689.     //Return the IPH_ACT_STA to the original one first,and compensate the IHS pre-delay
  1690.     //The h position must be equal after change the IHS delay and IPH_ACT_STA
  1691.     usIPH_ACT_STA   = CAP_WIN[ucMode_Curr][1];
  1692.     
  1693.     if(ucMode_Curr < MODE_0800x0600x75HZ)
  1694. Data[0] = 2;
  1695.     else if(ucMode_Curr < MODE_1280x1024x75HZ)
  1696. Data[0] = 5;
  1697.     else
  1698. Data[0] = 3;
  1699. //    usIPH_ACT_STA   = usIPH_ACT_STA + Data[0] - PROGRAM_HDELAY;
  1700. //usIPH_ACT_STA = usIPH_ACT_STA + 50 - (64 - (ucTemp1 >> 1));
  1701.     usIPH_ACT_STA = CAP_WIN[ucMode_Curr][1] + Data[0] - PROGRAM_HDELAY - (64 - (ucTemp1 >> 1));
  1702.     usTemp = usIPH_ACT_STA;
  1703. Set_H_Position();
  1704.         
  1705.     RTDSetByte(STATUS0_01, 0x00);  // Clear status
  1706.     RTDSetByte(STATUS1_1F, 0x00);  // Clear status
  1707.     
  1708. ///////////////////////////////////////////////////////////////////    
  1709.     ///////////////////////////////
  1710.     //   Measure  NOISE_MARGIN   //
  1711.     ///////////////////////////////
  1712.     Result  = Min_Noise_Margin();   
  1713.     Noise   = Data[0];
  1714.     
  1715.     
  1716.     //--------Auto_Clock-----------
  1717.     if (ERROR_SUCCEED == (Result & 0x80))
  1718.     {   
  1719.         stMUD.CLOCK = (stMUD.CLOCK) & 0xfc; // stMUD.CLOCK must be times of 4
  1720.         if (stMUD.CLOCK != Curr_Clock)  Set_Clock();
  1721.         ///////////////////////////////
  1722.         //       Adjust Clock        //
  1723.         ///////////////////////////////
  1724.         Result  = Auto_Clock_Do(Noise);
  1725.           
  1726.         if (ERROR_SUCCEED != (Result & 0x80))
  1727.         {
  1728.             if (stMUD.CLOCK != Curr_Clock)
  1729.             {
  1730.                 // Fail to find out suitable clock. Restore original clock and H position.
  1731.                 stMUD.H_POSITION    = Curr_PosH;
  1732.                 stMUD.CLOCK         = Curr_Clock;
  1733.                 Set_Clock();
  1734.                 Set_H_Position();
  1735.             }
  1736.         }
  1737.         else
  1738.         {
  1739.             stMUD.H_POSITION    = usH_Start + 128 + 64 - usIPH_ACT_STA - (stMUD.CLOCK >> 1);
  1740.             if (ucH_Max_Margin < stMUD.H_POSITION)
  1741.                 stMUD.H_POSITION    = ucH_Max_Margin;
  1742.             else if (ucH_Min_Margin > stMUD.H_POSITION)
  1743.                 stMUD.H_POSITION    = ucH_Min_Margin;
  1744.             Set_H_Position();
  1745.         }
  1746.     }
  1747.     
  1748.     //---------Auto_Phase-----------
  1749.     if (ERROR_SUCCEED == (Result & 0x80))
  1750.     {   
  1751.         Result      = Auto_Phase_Do(Noise);
  1752.         if (ERROR_SUCCEED != (Result & 0x80))
  1753.         {
  1754.             // Restore Phase
  1755.             stMUD.PHASE = Curr_Phase;
  1756.             Set_Phase(stMUD.PHASE);
  1757.             if (ERROR_NOTACTIVE == Result)      Result  = ERROR_SUCCEED;
  1758.         }
  1759.     }
  1760.     //---------Auto_Position-----------
  1761.     if (ERROR_SUCCEED == (Result & 0x80))    
  1762.     {   
  1763.         ///////////////////////////////
  1764.         //    Adjust (H/V)Position   //
  1765.         ///////////////////////////////
  1766.         Result  = Auto_Position_Do(Noise);
  1767.         // Because Auto_Position_Do() never returns bit-7 error, we don't have to check here.
  1768.     }
  1769.     else
  1770.     {
  1771.         stMUD.V_POSITION    = Curr_PosV;
  1772.         Set_V_Position();
  1773.     }
  1774.     
  1775. //    if (ERROR_SUCCEED == (Result & 0x80))   Save_MUD(ucMode_Curr);
  1776. //////////////////////////////////////////////////////////////////////////////
  1777. /*
  1778.     if(ucH_Min_Margin == (128 - ucTemp - (64 - (ucTemp1 >> 1))))
  1779. {
  1780.         if(usTemp != usIPH_ACT_STA)
  1781. {  //if usIPH_ACT_STA has been modified, turn back to original set value
  1782.            //stMUD.H_POSIITON also have to follow up the change of usIPH_ACT_STA
  1783.    stMUD.H_POSITION = stMUD.H_POSITION - (usTemp - usIPH_ACT_STA);
  1784.    usIPH_ACT_STA = usTemp - 50 + ucTemp + (64 - (ucTemp1 >> 1));
  1785. }
  1786. else
  1787.     usIPH_ACT_STA   = usIPH_ACT_STA - 50 + ucTemp + (64 - (ucTemp1 >> 1));
  1788. ucH_Min_Margin  = 128 - 50;   
  1789. Set_H_Position();
  1790. }
  1791. Set_Phase(stMUD.PHASE);
  1792. */
  1793. ////////////////////////////////////////////////////////////////////////////////
  1794. /////////////////////////////////////////////////////////////////////////////////
  1795.     if(ucH_Min_Margin == (128 - (64 - (ucTemp1 >> 1))))
  1796. {
  1797.         if(usTemp != usIPH_ACT_STA)
  1798. {  //if usIPH_ACT_STA has been modified, turn back to original set value
  1799.            //stMUD.H_POSIITON also have to follow up the change of usIPH_ACT_STA
  1800.    //Data[3] = 78 - usIPH_ACT_STA; Save the usIPH_ACT_STA compensate value
  1801.    stMUD.H_POSITION = stMUD.H_POSITION - (usTemp - usIPH_ACT_STA);
  1802.    usIPH_ACT_STA = usTemp - 50 + (64 - (ucTemp1 >> 1));
  1803.    Data[3] = 0x80 | (78 - stMUD.H_POSITION);     
  1804.          
  1805. }
  1806. else
  1807. {
  1808.     usIPH_ACT_STA   = usIPH_ACT_STA - 50 + (64 - (ucTemp1 >> 1));
  1809. Data[3] = 0;
  1810. }
  1811. // Save Frame-Sync Settings
  1812.            Data[0] = 4;
  1813.            Data[1] = ADDR_EROM1;
  1814.            Data[2] = (ucMode_Curr - 1);          
  1815.    
  1816.            
  1817.  if(0x80 < stMUD.H_POSITION)
  1818.          {
  1819.              if(stMUD.H_POSITION - 0x80 < 10)
  1820.              {
  1821.                  usIPH_ACT_STA += (stMUD.H_POSITION - 0x80);
  1822.                  Data[3] += (stMUD.H_POSITION - 0x80);
  1823.                  stMUD.H_POSITION = 0x80;                            
  1824.               }
  1825.          }
  1826.          else if(0x80 > stMUD.H_POSITION)
  1827.          {
  1828.               if(0x80 - stMUD.H_POSITION < 10)
  1829.               {
  1830.                  usIPH_ACT_STA -= (0x80 - stMUD.H_POSITION);
  1831.      Data[3] = (0x80 - stMUD.H_POSITION ) | 0x80;
  1832.                  stMUD.H_POSITION = 0x80;
  1833.               }
  1834.          }
  1835. I2CWrite(Data);
  1836.         Delay_Xms(SET_2404_DELAY);
  1837. ucH_Min_Margin  = 128 - 50;   
  1838. Set_H_Position();
  1839.         
  1840. }
  1841. Set_Phase(stMUD.PHASE);
  1842.     if (ERROR_SUCCEED == (Result & 0x80))   Save_MUD(ucMode_Curr);
  1843.     RTDSetByte(STATUS0_01, 0x00);  // Clear status
  1844.     RTDSetByte(STATUS1_1F, 0x00);  // Clear status
  1845. /////////////////////////////////////////////////////////////////////////////////
  1846.     // Restore ADC Gain/Offset
  1847. //  SetADC_GainOffset();
  1848.    
  1849.     bAutoInProgress = 0;
  1850.     Set_Phase(stMUD.PHASE);
  1851.     return Result;
  1852. }
  1853. unsigned char Auto_Balance(void)
  1854. {
  1855.     unsigned char Result, Curr_PosV;
  1856.     bAutoInProgress = 1;
  1857.     Curr_PosV   = stMUD.V_POSITION;     // Save current stMUD.V_POSITION
  1858.     if (ucV_Max_Margin < stMUD.V_POSITION)
  1859.     {
  1860.         stMUD.V_POSITION    = ucV_Max_Margin;
  1861.         Set_V_Position();
  1862.     }
  1863.     // Do ADC gain/offset adjust
  1864.     Result  = Tune_Balance();
  1865.     // Restore vertical position
  1866.     if (Curr_PosV != stMUD.V_POSITION)
  1867.     {
  1868.         stMUD.V_POSITION    = Curr_PosV;
  1869.         Set_V_Position();
  1870.     }
  1871.     if (ERROR_SUCCEED != Result)
  1872.     {
  1873.         // Restore ADC Gain/Offset
  1874.         Load_GUD2();
  1875.         SetADC_GainOffset();
  1876.     }
  1877.     else
  1878.     {
  1879.         stGUD0.CONTRAST         = 50;
  1880.         stGUD0.RTD_R_CONTRAST   = 50;
  1881.         stGUD0.RTD_G_CONTRAST   = 50;
  1882.         stGUD0.RTD_B_CONTRAST   = 50;
  1883.         stGUD0.RTD_R_BRIGHT     = 50;
  1884.         stGUD0.RTD_G_BRIGHT     = 50;
  1885.         stGUD0.RTD_B_BRIGHT     = 50;
  1886.         Set_Bright_Contrast();
  1887. #if(ANALOG_CONTRAST)
  1888.         SetADC_Gain();
  1889. #endif
  1890.         Save_GUD0();
  1891. /*
  1892.         if (0 != stGUD2.AD_G_GAIN && 255 != stGUD2.AD_G_GAIN && 0 != stGUD2.AD_G_OFFSET && 255 != stGUD2.AD_G_OFFSET)
  1893.         {
  1894.             stGUD2.AD_G_GAIN    += 1;
  1895.             stGUD2.AD_G_OFFSET  += 1;
  1896.         }
  1897.         SetADC_GainOffset();
  1898. */
  1899.         Save_GUD2();
  1900.     }
  1901.     bAutoInProgress = 0;
  1902.     return Result;
  1903. }
  1904. unsigned char Tune_Balance(void)
  1905. {
  1906.     unsigned char   Color, Count, Result, Margin, FineTune, Offset_Stop,ucTemp = 0;
  1907.     
  1908.     FineTune    = 0;
  1909. #if(ANALOG_CONTRAST)
  1910.     ucTemp = stGUD0.CONTRAST;
  1911.     stGUD0.CONTRAST = 50;
  1912. SetADC_Gain();
  1913. #endif
  1914.     RTDCodeW(ADC_DEFAULT);
  1915.     
  1916.     // Get usVer_Start, usVer_End, usH_Start, usH_Start
  1917.     if (ERROR_SUCCEED != Measure_PositionN(0x40))   return ERROR_ABORT;
  1918.     if (ERROR_SUCCEED != Measure_Color(SELECT_RED, COLOR_MAX))      return ERROR_ABORT;
  1919.     if (0x60 > Data[0])     return ERROR_ABORT;
  1920.     
  1921.     Margin  = Data[0];
  1922.     if (ERROR_SUCCEED != Measure_Color(SELECT_GREEN, COLOR_MAX))    return ERROR_ABORT;
  1923.     if (0x60 > Data[0])     return ERROR_ABORT;
  1924.     Margin  = Margin > Data[0] ? Data[0] : Margin;
  1925.     if (ERROR_SUCCEED != Measure_Color(SELECT_BLUE, COLOR_MAX))     return ERROR_ABORT;
  1926.     if (0x60 > Data[0])     return ERROR_ABORT;
  1927.     Margin  = Margin > Data[0] ? Data[0] : Margin;
  1928.     Margin  = (Margin - 0x20) & 0xfc;
  1929.     // Get usVer_Start, usVer_End, usH_Start, usH_Start
  1930.     if (ERROR_SUCCEED != Measure_PositionN(Margin))   return ERROR_ABORT;
  1931. #if(0)
  1932.     SetADC_Offset();
  1933. #else
  1934. SetADC_GainOffset();
  1935. #endif
  1936. Offset_Stop = 0;
  1937.     Color   = SELECT_BLUE;
  1938.     do
  1939.     {
  1940.         Count   = 0x30;
  1941.         
  1942.         do
  1943.         {
  1944. #if (0)
  1945.             
  1946.            if(Offset_Stop == 0)
  1947.            { 
  1948.    ///////////////////////////////
  1949.    // Minimum Adjustment (0x02) //
  1950.    ///////////////////////////////
  1951.    if (ERROR_SUCCEED != Measure_Color(Color, COLOR_MIN))   return ERROR_ABORT;
  1952.    Margin  = Data[0];
  1953.    if (0x0a < Margin)
  1954.    {
  1955.    Change_ADC_Offset(Color, 0x08, 0);          // Increase Offset; Decrease Brightness
  1956.    }
  1957.    else if (0x02 < Margin)
  1958.    {
  1959.    Change_ADC_Offset(Color, Margin - 0x02, 0); // Increase Offset; Decrease Brightness
  1960.    }
  1961.    else if (0x02 > Margin)
  1962.    {
  1963.    if (0x00 == Margin && 0 == FineTune)
  1964.    Change_ADC_Offset(Color, 0x06, 1);              // Decrease Offset; Increase Brightness
  1965.    else
  1966.    {
  1967.    Change_ADC_Offset(Color, 0x02 - Margin, 1);     // Decrease Offset; Increase Brightness
  1968.    if(Color == SELECT_RED)
  1969.    {
  1970.    Offset_Stop = 1;
  1971.    SetADC_Gain();
  1972.    Color   = SELECT_BLUE << 1;
  1973.    }
  1974.    break;
  1975.    }
  1976.    }
  1977.    }
  1978.    else
  1979.    {
  1980.    ///////////////////////////////
  1981.    // Maximum Adjustment (0xf2) //
  1982.    ///////////////////////////////
  1983.    if (ERROR_SUCCEED != Measure_Color(Color, COLOR_MAX))   return ERROR_ABORT;
  1984.    Margin  = Data[0];
  1985.    if (0xf2 < Margin) 
  1986.    {
  1987.    Result  = Margin - 0xf2;
  1988.    
  1989.    // Non-zero return value of Change_ADC_Gain() means ADC gain reaches maximum.
  1990.    if (Change_ADC_Gain(Color, Result, 0))              // Increase Gain; Decrease Contrast
  1991.    {
  1992.    if (Change_ADC_Offset(Color, 4, 0))     break;  // Increase Offset; Decrease Brightness
  1993.    }
  1994.    }
  1995.    else if (0xf2 > Margin)
  1996.    {
  1997.    Result  = 0xf2 - Margin;
  1998.    // Non-zero return value of Change_ADC_Gain() means ADC gain reaches minimum.                
  1999.    if (Change_ADC_Gain(Color, Result, 1))     // Decrease Gain; Increase Contrast
  2000.    {
  2001.    if (Change_ADC_Offset(Color, 4, 1))     break;  // Decrease Offset; Increase Brightness
  2002.    }
  2003.    }
  2004.    else
  2005.    break;
  2006.    }
  2007.    if (8 < Count && 0xf3 >= Result && 0xf1 <= Result && 0x03 >= Margin && 0x01 <= Margin)
  2008.    {
  2009.    FineTune    = 1;
  2010.    Count       = 8;
  2011.    }
  2012. #endif
  2013. #if(1)
  2014.             ///////////////////////////////
  2015.             // Maximum Adjustment (0xf2) //
  2016.             ///////////////////////////////
  2017.             if (ERROR_SUCCEED != Measure_Color(Color, COLOR_MAX))   return ERROR_ABORT;
  2018.             Margin  = Data[0];
  2019.             if (0xf2 < Margin)
  2020.             {
  2021.                 Result  = Margin - 0xf2;
  2022.                 
  2023.                 // Non-zero return value of Change_ADC_Gain() means ADC gain reaches maximum.
  2024.                 if (Change_ADC_Gain(Color, Result, 0))              // Increase Gain; Decrease Contrast
  2025.                 {
  2026.                     if (Change_ADC_Offset(Color, 4, 0))     break;  // Increase Offset; Decrease Brightness
  2027.                 }
  2028.             }
  2029.             else if (0xf2 > Margin)
  2030.             {
  2031.                 Result  = 0xf2 - Margin;
  2032.                 // Non-zero return value of Change_ADC_Gain() means ADC gain reaches minimum.
  2033.                 if (Change_ADC_Gain(Color, Result, 1))              // Decrease Gain; Increase Contrast
  2034.                 {
  2035.                     if (Change_ADC_Offset(Color, 4, 1))     break;  // Decrease Offset; Increase Brightness
  2036.                 }
  2037.             }
  2038.             Result  = Margin;
  2039.             ///////////////////////////////
  2040.             // Minimum Adjustment (0x02) //
  2041.             ///////////////////////////////
  2042.             
  2043.             if (ERROR_SUCCEED != Measure_Color(Color, COLOR_MIN))   return ERROR_ABORT;
  2044.             Margin  = Data[0];
  2045.             if (0x0a < Margin)
  2046.             {
  2047.                 Change_ADC_Offset(Color, 0x08, 0);          // Increase Offset; Decrease Brightness
  2048.             }
  2049.             else if (0x02 < Margin)
  2050.             {
  2051.                 Change_ADC_Offset(Color, Margin - 0x02, 0); // Increase Offset; Decrease Brightness
  2052.             }
  2053.             else if (0x02 > Margin)
  2054.             {
  2055.                 if (0x00 == Margin && 0 == FineTune)
  2056.                     Change_ADC_Offset(Color, 0x06, 1);              // Decrease Offset; Increase Brightness
  2057.                 else
  2058.                     Change_ADC_Offset(Color, 0x02 - Margin, 1);     // Decrease Offset; Increase Brightness
  2059.             }
  2060.             else if (0xf2 == Result)
  2061.             {
  2062.                 break;
  2063.             }
  2064.             // Prevent redundant fine tune
  2065.             if (8 < Count && 0xf3 >= Result && 0xf1 <= Result && 0x03 >= Margin && 0x01 <= Margin)
  2066.             {
  2067.                 FineTune    = 1;
  2068.                 Count       = 8;
  2069.             }
  2070. #endif
  2071. #if(0)
  2072.             ///////////////////////////////
  2073.             // Maximum Adjustment (0xfd) //
  2074.             ///////////////////////////////
  2075.             if (ERROR_SUCCEED != Measure_Color(Color, COLOR_MAX))   return ERROR_ABORT;
  2076.             Margin  = Data[0];
  2077.             if (0xfd < Margin)
  2078.             {
  2079.                 Result  = (0xff == Margin && 0 == FineTune) ? 0x06 : Margin - 0xfd;
  2080.                 
  2081.                 // Non-zero return value of Change_ADC_Gain() means ADC gain reaches maximum.
  2082.                 if (Change_ADC_Gain(Color, Result, 0))              // Increase Gain; Decrease Contrast
  2083.                 {
  2084.                     if (Change_ADC_Offset(Color, 4, 0))     break;  // Increase Offset; Decrease Brightness
  2085.                 }
  2086.             }
  2087.             else if (0xfd > Margin)
  2088.             {
  2089.                 Result  = (0xf1 > Margin) ? 0x0c : 0xfd - Margin;
  2090.                 // Non-zero return value of Change_ADC_Gain() means ADC gain reaches minimum.
  2091.                 if (Change_ADC_Gain(Color, Result, 1))              // Decrease Gain; Increase Contrast
  2092.                 {
  2093.                     if (Change_ADC_Offset(Color, 4, 1))     break;  // Decrease Offset; Increase Brightness
  2094.                 }
  2095.             }
  2096.             Result  = Margin;
  2097.             ///////////////////////////////
  2098.             // Minimum Adjustment (0x02) //
  2099.             ///////////////////////////////
  2100.             
  2101.             if (ERROR_SUCCEED != Measure_Color(Color, COLOR_MIN))   return ERROR_ABORT;
  2102.             Margin  = Data[0];
  2103.             if (0x0a < Margin)
  2104.             {
  2105.                 Change_ADC_Offset(Color, 0x08, 0);          // Increase Offset; Decrease Brightness
  2106.             }
  2107.             else if (0x02 < Margin)
  2108.             {
  2109.                 Change_ADC_Offset(Color, Margin - 0x02, 0); // Increase Offset; Decrease Brightness
  2110.             }
  2111.             else if (0x02 > Margin)
  2112.             {
  2113.                 if (0x00 == Margin && 0 == FineTune)
  2114.                     Change_ADC_Offset(Color, 0x06, 1);              // Decrease Offset; Increase Brightness
  2115.                 else
  2116.                     Change_ADC_Offset(Color, 0x02 - Margin, 1);     // Decrease Offset; Increase Brightness
  2117.             }
  2118.             else if (0xfd == Result)
  2119.             {
  2120.                 break;
  2121.             }
  2122.             // Prevent redundant fine tune
  2123.             if (8 < Count && 0xfe >= Result && 0xfc <= Result && 0x03 >= Margin && 0x01 <= Margin)
  2124.             {
  2125.                 FineTune    = 1;
  2126.                 Count       = 8;
  2127.             }
  2128. #endif
  2129.         }
  2130.         while (--Count);
  2131.         Color   = Color >> 1;
  2132.     }
  2133.     while (Color);
  2134. #if(ANALOG_CONTRAST)
  2135.     stGUD0.CONTRAST = ucTemp;
  2136.     SetADC_Gain();
  2137. #endif 
  2138.     return ERROR_SUCCEED; 
  2139. }
  2140. unsigned char Measure_Color(unsigned char color, unsigned char margin)
  2141. {
  2142.     RTDSetByte(MARGIN_B_7D, (SELECT_RED == color) ? COLORS_RED : (SELECT_GREEN == color) ? COLORS_GREEN : COLORS_BLUE);
  2143.     Data[0] = 9;
  2144.     Data[1] = Y_INC;
  2145.     Data[2] = H_BND_STA_L_75;
  2146.     Data[3] = (unsigned char)(usH_Start + MEAS_H_STA_OFFSET - 1);
  2147.     Data[4] = (unsigned char)(usH_End + MEAS_H_END_OFFSET);
  2148.     Data[5] = ((unsigned char)((usH_Start + MEAS_H_STA_OFFSET - 1) >> 4) & 0x70) | ((unsigned char)((usH_End + MEAS_H_END_OFFSET) >> 8) & 0x0f);
  2149.     if (COLOR_MIN == margin)
  2150.     {
  2151.         Data[3] = 0x80;
  2152.         Data[4] = 0x00;
  2153.         Data[5] = 0x12;
  2154.         Data[6] = 9 < usVer_Start ? 9 : usVer_Start - 1;
  2155.         Data[7] = Data[6] + 1;
  2156.         Data[8] = 0;
  2157.     }
  2158.     else
  2159.     {
  2160.         Data[6] = (unsigned char)(usVer_Start + 1);
  2161.         Data[7] = (unsigned char)(usVer_End + 1);
  2162.         Data[8] = ((unsigned char)((usVer_Start + 1) >> 4) & 0x70) | ((unsigned char)((usVer_End + 1) >> 8) & 0x0f);
  2163.     }
  2164.     Data[9] = 0;
  2165.     RTDWrite(Data);
  2166.     if (COLOR_MIN == margin)
  2167.      RTDSetByte(AUTO_ADJ_CTRL_7F, COLOR_MIN | 0x01); // Start the auto-adjust
  2168. else
  2169.      RTDSetByte(AUTO_ADJ_CTRL_7F, COLOR_MAX | 0x01); // Start the auto-adjust
  2170.     Wait_Finish();
  2171.     if (ERROR_SUCCEED != Data[0])   return ERROR_ABORT;
  2172.     RTDRead(AUTO_BAL_RESULT_88, 1, N_INC);  // Store result in Data[0]
  2173.    
  2174.     if (COLOR_MIN == margin) Data[0] ^= 0xff;
  2175.     return ERROR_SUCCEED;
  2176. }
  2177. unsigned char Change_ADC_Gain(unsigned char color, unsigned char delta, unsigned char inc)
  2178. {
  2179.     if (inc)
  2180.     {
  2181.         inc = 0;
  2182.         if (color & SELECT_RED)
  2183.         {
  2184.             if (stGUD2.AD_R_GAIN > delta)
  2185.                 stGUD2.AD_R_GAIN    -= delta;
  2186.             else
  2187.             {
  2188.                 stGUD2.AD_R_GAIN    = 0;
  2189.                 inc |= SELECT_RED;
  2190.             }
  2191.         }
  2192.         if (color & SELECT_GREEN)
  2193.         {
  2194.             if (stGUD2.AD_G_GAIN > delta)
  2195.                 stGUD2.AD_G_GAIN    -= delta;
  2196.             else
  2197.             {
  2198.                 stGUD2.AD_G_GAIN    = 0;
  2199.                 inc |= SELECT_GREEN;
  2200.             }
  2201.         }
  2202.         if (color & SELECT_BLUE)
  2203.         {
  2204.             if (stGUD2.AD_B_GAIN > delta)
  2205.                 stGUD2.AD_B_GAIN    -= delta;
  2206.             else
  2207.             {
  2208.                 stGUD2.AD_B_GAIN    = 0;
  2209.                 inc |= SELECT_BLUE;
  2210.             }
  2211.         }
  2212.     }
  2213.     else
  2214.     {
  2215.         if (color & SELECT_RED)
  2216.         {
  2217.             if ((0xff - stGUD2.AD_R_GAIN) > delta)
  2218.                 stGUD2.AD_R_GAIN    += delta;
  2219.             else
  2220.             {
  2221.                 stGUD2.AD_R_GAIN    = 0xff;
  2222.                 inc |= SELECT_RED;
  2223.             }
  2224.         }
  2225.         if (color & SELECT_GREEN)
  2226.         {
  2227.             if ((0xff - stGUD2.AD_G_GAIN) > delta)
  2228.                 stGUD2.AD_G_GAIN    += delta;
  2229.             else
  2230.             {
  2231.                 stGUD2.AD_G_GAIN    = 0xff;
  2232.                 inc |= SELECT_GREEN;
  2233.             }
  2234.         }
  2235.         if (color & SELECT_BLUE)
  2236.         {
  2237.             if ((0xff - stGUD2.AD_B_GAIN) > delta)
  2238.                 stGUD2.AD_B_GAIN    += delta;
  2239.             else
  2240.             {
  2241.                 stGUD2.AD_B_GAIN    = 0xff;
  2242.                 inc |= SELECT_BLUE;
  2243.             }
  2244.         }
  2245.     }
  2246.     SetADC_Gain();
  2247.     
  2248.     return inc;
  2249. }
  2250. unsigned char Change_ADC_Offset(unsigned char color, unsigned char delta, unsigned char inc)
  2251. {
  2252.     if (inc)
  2253.     {
  2254.         inc = 0;
  2255.         if (color & SELECT_RED)
  2256.         {
  2257.             if (stGUD2.AD_R_OFFSET > delta)
  2258.                 stGUD2.AD_R_OFFSET  = stGUD2.AD_R_OFFSET - delta;
  2259.             else
  2260.             {
  2261.                 stGUD2.AD_R_OFFSET  = 0;
  2262.                 inc |= SELECT_RED;
  2263.             }
  2264.         }
  2265.         if (color & SELECT_GREEN)
  2266.         {
  2267.             if (stGUD2.AD_G_OFFSET > delta)
  2268.                 stGUD2.AD_G_OFFSET  = stGUD2.AD_G_OFFSET - delta;
  2269.             else
  2270.             {
  2271.                 stGUD2.AD_G_OFFSET  = 0;
  2272.                 inc |= SELECT_GREEN;
  2273.             }
  2274.         }
  2275.         if (color & SELECT_BLUE)
  2276.         {
  2277.             if (stGUD2.AD_B_OFFSET > delta)
  2278.                 stGUD2.AD_B_OFFSET  = stGUD2.AD_B_OFFSET - delta;
  2279.             else
  2280.             {
  2281.                 stGUD2.AD_B_OFFSET  = 0;
  2282.                 inc |= SELECT_BLUE;
  2283.             }
  2284.         }
  2285.     }
  2286.     else
  2287.     {
  2288.         if (color & SELECT_RED)
  2289.         {
  2290.             if ((0xff - delta) > stGUD2.AD_R_OFFSET)
  2291.                 stGUD2.AD_R_OFFSET  = stGUD2.AD_R_OFFSET + delta;
  2292.             else
  2293.             {
  2294.                 stGUD2.AD_R_OFFSET  = 0xff;
  2295.                 inc |= SELECT_RED;
  2296.             }
  2297.         }
  2298.         if (color & SELECT_GREEN)
  2299.         {
  2300.             if ((0xff - delta) > stGUD2.AD_G_OFFSET)
  2301.                 stGUD2.AD_G_OFFSET  = stGUD2.AD_G_OFFSET + delta;
  2302.             else
  2303.             {
  2304.                 stGUD2.AD_G_OFFSET  = 0xff;
  2305.                 inc |= SELECT_GREEN;
  2306.             }
  2307.         }
  2308.         if (color & SELECT_BLUE)
  2309.         {
  2310.             if ((0xff - delta) > stGUD2.AD_B_OFFSET)
  2311.                 stGUD2.AD_B_OFFSET  = stGUD2.AD_B_OFFSET + delta;
  2312.             else
  2313.             {
  2314.                 stGUD2.AD_B_OFFSET  = 0xff;
  2315.                 inc |= SELECT_BLUE;
  2316.             }
  2317.         }
  2318.     }
  2319.     SetADC_Offset();
  2320.     
  2321.     return inc;
  2322. }