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

C/C++

  1. #define __FRAMESYNC__
  2. #include "HeaderFrame_Sync.h"
  3. #include "HeaderLcd_func.h"
  4. #include "HeaderAccess.h"
  5. #include "HeaderMain_def.h"
  6. #include "HeaderConfig.h"
  7. #include "HeaderLcd_main.h"
  8. #include "HeaderLCD_OSD.h"
  9.         /////////////////////////
  10.         // Frame-Sync Detector //
  11.         /////////////////////////
  12. bit Frame_Sync_Detector(void)
  13. {
  14.         if (bPower_Status && bStable && MODE_NOSIGNAL != ucMode_Curr && MODE_NOSUPPORT != ucMode_Curr)
  15.         {
  16.             if (bFrameSync)
  17.             {
  18.                 RTDRead(STATUS1_1F, 1, N_INC);
  19.                 ucStatus    |= (Data[0] >> 6);
  20. if(Data[0])
  21. RTDSetByte(STATUS1_1F,0x00);
  22.                 if (Data[0] & 0xc0)
  23.                 {
  24.                     ucSyncErrorCnt  += 1;
  25. #if (RTDDEBUG)
  26.                     if (0xff > ucDebug)     ucDebug ++; 
  27. #endif
  28.                 }
  29. //#if (DISP_BIT == DISP_18BIT)
  30. //                else if (Data[0] & 0x04)
  31. //                {
  32. //                    bDitherToggle   = !bDitherToggle;
  33. //                    if (bDitherToggle)
  34. //                    {
  35. //                        bDitherTable    = !bDitherTable;
  36. //                        WriteDither(bDitherTable ? DITHER_1 : DITHER_2);
  37. //                    }
  38. //                }
  39. //#endif
  40.             }
  41.             if (SYNC_FAIL_TIMES >= ucSyncErrorCnt)
  42.             {
  43.                 RTDRead(STATUS0_01, 1, N_INC);
  44.                 ucStatus    |= (Data[0] & 0xfc);
  45. if(Data[0])
  46. RTDSetByte(STATUS0_01,0x00); //if some event happened, write once to clear status
  47.                
  48.                 if (Data[0] & 0x60)     ucSyncErrorCnt  += (SYNC_FAIL_TIMES + 1);
  49.                 if (SOURCE_VGA == (stGUD1.INPUT_SOURCE & 0x07))
  50.                 {
  51.                     if (Data[0] & 0x80)
  52.                     {
  53.                         ucSyncErrorCnt  += 1;
  54. #if (RTDDEBUG)
  55.                         if (0xff > ucDebug)     ucDebug ++;                       
  56. #endif
  57.                     }
  58.                     else
  59.                     {
  60. #if(TUNE_APLL)
  61.                   RTDSetBit(DV_TOTAL_STATUS_3D, 0x7f, 0x20); //Enable PE Max Measurement
  62.   Delay_Xms(1);
  63.               RTDRead(DV_TOTAL_STATUS_3D, 1, N_INC);
  64.               ucPE_Max = Data[0] & 0x1f;
  65.   if((ucPE_Max > 0x10) && (ucPE_Level == 0))
  66.   {
  67.       ucPE_Level = 1;
  68.   Adjust_I_Code();
  69.                       if((ucI_Code & 0x80) == 0x80)
  70.                          RTDSetBit(I_CODE_MB_CA,0xdf,0x20);  //Set the I_Code[13] to 1;
  71.                       else
  72.                          RTDSetBit(I_CODE_MB_CA,0xdf,0x00);  //Set the I_Code[13] to 0;
  73.                       
  74.                       ucI_Code = ucI_Code & 0x7f;
  75.                   RTDSetByte(I_CODE_LB_C9,0x1c | ((ucI_Code & 0x07) << 5));
  76.                   RTDSetBit(I_CODE_MB_CA,0xfc,0x04 | ((ucI_Code & 0x18) >> 3));
  77.   RTDSetBit(DV_TOTAL_STATUS_3D, 0xdf, 0x00);//Disable PE Max Measurement
  78.                       RTDSetByte(DV_TOTAL_STATUS_3D,0x40); //clear PE Max value
  79.   ucPE_Max = 0;
  80.   }
  81.   
  82. #endif
  83.                     }
  84.                 }
  85.             }
  86.             if (SYNC_FAIL_TIMES < ucSyncErrorCnt)
  87.             {
  88.                 Reset_Mode();
  89.                 Set_Task(STATE_MODECHANGE);     // Notify Task State Machine
  90.                 bNotify_Timer0_Int  = 0;
  91.                 return _TRUE;
  92.                 //continue;                       // leave current iteration.
  93.             }
  94.             if (bNotify_Timer0_Int && MODE_DETECT_FREQ == ucModeCnt)
  95.             {
  96.                 if (ucSyncErrorCnt)     ucSyncErrorCnt  -= 1;
  97.             }
  98.         }
  99.         return _FALSE;
  100. }
  101. /////////////////////////////////////////////////////////////////////////////////
  102. // FrameSync fine-tune routines
  103. /////////////////////////////////////////////////////////////////////////////////
  104. void AbortSync(void)
  105. {
  106.     Data[0] = 5;
  107.     Data[1] = Y_INC;
  108.     Data[2] = DH_TOTAL_22;
  109.     Data[3] = (unsigned char)usDH_Total;
  110.     Data[4] = (unsigned char)(usDH_Total >> 8);
  111.     Data[5] = 0;
  112.     RTDWrite(Data);
  113.     RTDSetBit(DV_TOTAL_H_2E, 0x07, 0x00);
  114. }
  115. unsigned char TestSync(unsigned int offset)     // 0 - Success; Otherwise - Fail
  116. {
  117. RTDSetByte(DCLK_OFFSET_LSB_9A,(unsigned char)offset);
  118. RTDSetBit(DCLK_OFFSET_MSB_9B,0xf0,(unsigned char)((offset >> 8) & 0x0f) | 0x20);
  119.     //RTDSetBit(DV_TOTAL_H_2E, 0x07, fine & 0xf8);
  120.     Wait_For_Event(EVENT_DVS);          // Wait for Frame End
  121.     //Delay_Xms(10);
  122. RTDSetByte(STATUS0_01,0x00);
  123.     Wait_For_Event(EVENT_DVS);          // Wait for Frame End
  124.     //RTDSetByte(STATUS0_01,0x00);////
  125. /*
  126.     if (SOURCE_VGA != (stGUD1.INPUT_SOURCE & 0x07))
  127.     {
  128.         Wait_For_Event(EVENT_DVS);      // Wait for Frame End
  129.     }
  130. */
  131.     Wait_For_Event(EVENT_DVS);          // Wait for Frame End
  132. //RTDSetByte(STATUS0_01,0x00);////
  133. //Delay_Xms(10);
  134.     RTDRead(STATUS0_01, 1, N_INC);      // Get status
  135. if(Data[0])
  136.     RTDSetByte(STATUS0_01,0x00);
  137.     if (Data[0] & 0x60) // Mode Changed
  138.     {
  139.         AbortSync();
  140.         return 1;
  141.     }
  142.     Data[0] &= 0x03;
  143.     return 0;   // Success
  144. }
  145. //Returned value
  146. // 0 : Succeed(Frame-sync settings returned in Data[3] and Data[4])
  147. // 1 : Fail
  148. // 2 : Abort
  149. #define Offset_Step      32//16 //This value should better larger then 16
  150. unsigned char Frame_Sync(void)
  151. {
  152.    unsigned int idata usBuffer,usDelta;
  153.    unsigned char idata  ucFine,ucTemp=0;
  154. #if(FIX_LAST_DHT)
  155.    unsigned int idata usMax_Last_Line,usMin_Last_Line;
  156. #endif
  157.    RTDRead(DCLK_OFFSET_LSB_9A , 2, Y_INC);
  158.    Data[2] = Data[1] & 0x0f;
  159.    Data[3] = Data[0];
  160.    usBuffer = ((unsigned int*)Data)[1];//get the DCLK offset
  161.    //usDelta = ((unsigned int*)Data)[1];//get the DCLK offset
  162.    usDelta = usBuffer;
  163. //   ucFine = 0;
  164.    if(((stGUD1.INPUT_SOURCE & 0x07) == SOURCE_VGA) || ((stGUD1.INPUT_SOURCE & 0x07) == SOURCE_DVI))
  165.    {
  166.    //while(usDelta < Offset_Step * 14) 
  167.    while(usBuffer < (1228 + 14 * Offset_Step))
  168.    //while(usBuffer < (1228 + 24 * Offset_Step)) //eric 0729 issue: dvi flash
  169.    {
  170.    RTDRead(DPLL_M_D1,2,Y_INC);
  171.    RTDSetByte(DPLL_M_D1,Data[0]+1);
  172.    RTDSetByte(DPLL_N_D2,Data[1]);
  173. //     Forster :
  174. //     if the DCLK offset too small, then set the M_Code = M_Code + 1
  175. //     And reculculate the offset
  176. //     Original formula:
  177. //     24.576M * M/N - 24.576M*M/N/2^15*old_offset = 24.576M*(M+1)/N - 24.576M*(M+1)/N/2^15*new_offset
  178. //     => new_offset = (2^15 + M*old_offset) / (M+1);
  179.    usBuffer = (unsigned int)((unsigned long)(32768 + (unsigned long)(Data[0] + 2) * usBuffer)/(unsigned long)(Data[0] + 3));
  180.    //usBuffer = (32768 + (Data[0] + 2) * usDelta)/(Data[0] + 3);
  181.    usDelta = usBuffer;
  182.        
  183.    }
  184. /*   //Below spend more code size
  185.    ((unsigned int*)Data)[1] = 1228 + 14 * Offset_Step;
  186.    if(usBuffer < ((unsigned int*)Data)[1])
  187.    {
  188.    RTDRead(DPLL_M_D1,1,N_INC);
  189.    
  190.    ucFine =(unsigned char)((unsigned long)(Data[0] + 2) * (((unsigned int*)Data)[1] - usBuffer)/(unsigned long)(32768 - ((unsigned int*)Data)[1]));
  191.    usBuffer = (unsigned int)(((unsigned long)32768 * (ucFine + 1) + (unsigned long)(Data[0] + 2) * usBuffer)/(unsigned long)(Data[0] + 2 + (ucFine + 1)));
  192.    RTDSetByte(DPLL_M_D1,Data[0] + ucFine + 1);
  193.    RTDSetBit(DPLL_N_D2,0xf8,USER_MODE_NCODE - 2);
  194.    }
  195.    usDelta = usBuffer;
  196. */   
  197.    usDelta -= 128; //Clk offset fine-tune
  198.    }
  199.    usBuffer = usDelta;
  200.   
  201.    for(ucFine =0;ucFine < 14;ucFine++)
  202.    {
  203.    if (TestSync(usDelta))    return 2;
  204.    if(Data[0] & 0x03)
  205.    {
  206.    usDelta = (Data[0] & 0x02) ? usDelta - Offset_Step : usDelta + Offset_Step;
  207.    ucTemp += 1;
  208.    }
  209.    else if((Data[0] & 0x03) == 0)
  210.    break;
  211.    }
  212.    if(Data[0] & 0x03)
  213.           return 1;   // Frame sync fail  
  214. #if(SPREAD_SPECTRUM)
  215.    else if(usDelta < usBuffer) //Get more margin of Framesync
  216.    {
  217.    //usDelta -= 2;
  218.    if(TestSync(usDelta - 4))    return 2;
  219.    if(Data[0] & 0x03)
  220.        TestSync(usDelta);
  221.    else
  222.        usDelta -= 2;
  223.    
  224.    }
  225.    else//(usDelta > usBuffer) //Get more margin of Framesync
  226.    {
  227.    //usDelta += 2;
  228.    if(TestSync(usDelta + 4))    return 2;
  229.    if(Data[0] & 0x03)
  230.        TestSync(usDelta);
  231.    else 
  232.        usDelta += 2;
  233.    }
  234. #endif   
  235. //   ucDebug_Value0 = ucTemp;
  236. #if(FIX_LAST_DHT)
  237.    //Disable spread spectrum
  238. #if(SPREAD_SPECTRUM)
  239.     RTDSetBit(SPREAD_SPECTRUM_99,0x0f,0x00);
  240. RTDSetBit(DCLK_OFFSET_MSB_9B,0xff,0x20);
  241. #endif
  242.  
  243.        //Read the last line information , read back data equal to half last line length
  244.    RTDRead(LAST_LINE_H_2C, 1, N_INC);
  245.        usMax_Last_Line = (unsigned int)(Data[0] & 0xf8) << 2;
  246.        RTDRead(LAST_LINE_L_26, 1, N_INC);
  247.        usMax_Last_Line = usMax_Last_Line + (Data[0] / 8);
  248.         
  249.     
  250.    
  251.    //Read the last line information when frequency offset set one more step
  252.    RTDSetByte(DCLK_OFFSET_LSB_9A,(unsigned char)(usDelta + 1));
  253.    RTDSetBit(DCLK_OFFSET_MSB_9B,0xf0,(unsigned char)(((usDelta + 1) >> 8) & 0x07) | 0x20);
  254.    Wait_For_Event(EVENT_IVS);
  255.    Wait_For_Event(EVENT_IVS);
  256.    RTDRead(LAST_LINE_H_2C, 1, N_INC);
  257.        usMin_Last_Line = (unsigned int)(Data[0] & 0xf8) << 2;
  258.        RTDRead(LAST_LINE_L_26, 1, N_INC);
  259.        usMin_Last_Line = usMin_Last_Line + (Data[0] / 8);
  260.     
  261.    //Calculate the difference of last line when increase one offset step
  262.    if(usMin_Last_Line < usMax_Last_Line)
  263.    usMin_Last_Line = usMax_Last_Line - usMin_Last_Line;
  264.    else
  265.    usMin_Last_Line = usDH_Total/2 - usMin_Last_Line + usMax_Last_Line;
  266.    if(FIX_LAST_DHT > usMax_Last_Line)
  267.    {
  268.            if((FIX_LAST_DHT - usMax_Last_Line) > (usDH_Total / 4)) 
  269.    {   //decrease the last line, decrease the DClk
  270.    Data[0] = (unsigned int)(usMax_Last_Line + (usDH_Total / 2 - FIX_LAST_DHT)) / usMin_Last_Line;
  271.    usDelta = usDelta + Data[0];
  272.    }
  273.    else
  274.    {   //increase the last line, increase the DClk
  275.    Data[0] = (unsigned int)(FIX_LAST_DHT - usMax_Last_Line) / usMin_Last_Line; 
  276.    usDelta = usDelta - (Data[0] + 1);
  277.    }
  278.    }
  279.    else
  280.    {
  281.    if((usMax_Last_Line - FIX_LAST_DHT) > (usDH_Total / 4)) 
  282.    {   //increase the last line, increase the DClk
  283.    Data[0] = (unsigned int)(FIX_LAST_DHT + (usDH_Total / 2 - usMax_Last_Line)) / usMin_Last_Line;
  284.    usDelta = usDelta - (Data[0] + 1);
  285.    }
  286.    else
  287.    {   //decrease the last line, decrease the DClk
  288.    Data[0] = (usMax_Last_Line - FIX_LAST_DHT) / usMin_Last_Line; 
  289.    Data[11] = Data[0];
  290.    usDelta += Data[0];
  291.    
  292.    }
  293.    }
  294.  //Enable the apread spectrum again
  295. #if (SPREAD_SPECTRUM)
  296.     RTDSetBit(SPREAD_SPECTRUM_99,0x0f,(DCLK_SPRED_RANGE << 4));
  297.     if(TestSync(usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE]))    
  298.    return 2;
  299. if(Data[0] & 0x03)
  300. {
  301.        if(TestSync((Data[0] & 0x02) ? (usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE] - 1)
  302.                                 : (usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE] + 1)))  //Fine tune Dclk offset 
  303.       return 2;
  304.    else
  305.    {
  306.           if(Data[0] & 0x03)
  307.      return 1; //frame sync fail!
  308.   else
  309.                  return 0;
  310.    }
  311. }
  312. #else
  313.     if(TestSync(usDelta))    return 2;
  314. #endif
  315.    RTDSetByte(FX_LST_LEN_L_59,(unsigned char)(FIX_LAST_DHT << 1));
  316.    RTDSetBit(FX_LST_LEN_H_5A,0x08,(unsigned char)((FIX_LAST_DHT >> 7) & 0x07));
  317.         RTDRead(DV_ACT_END_34, 2, Y_INC);
  318.         Data[2] = Data[1] & 0x07;
  319.         Data[3] = Data[0];
  320.         Data[4] = ((Data[1] & 0xf0) >> 4); //Measure result of last 16 line of DVTotal, including the un-complete last line
  321.     
  322.         // Get Output_Active Height
  323.         ((unsigned int *)Data)[1]   = ((unsigned int *)Data)[1] - DV_ACT_STA_POS;
  324.         // Original Idea :
  325.         // DVTotal  = Output_Active_Line * (Input_Total_Line / Input_Active_Line) 
  326.         usDelta = (unsigned long)usVsync * ((unsigned int *)Data)[1] / usIPV_ACT_LEN;
  327.         usDelta = (usDelta & 0xfff0 | Data[4]); 
  328. RTDSetByte(FIX_DVTOTAL_LSB_97,(unsigned char)usDelta);
  329. RTDSetByte(FIX_DVTOTAL_MSB_98,(unsigned char)((usDelta >> 8) & 0x07));
  330.         RTDSetBit(SPREAD_SPECTRUM_99,0xfc,0x03); //Frequency Synthesis select N = 4
  331. RTDSetBit(DCLK_OFFSET_MSB_9B,0xff,0x20);
  332. //     RTDSetBit(FX_LST_LEN_H_5A,0xff,0x10); //Enable the Fixed DVTOTAL & Last Line Lenghth Fucntion
  333. //     RTDSetBit(FX_LST_LEN_H_5A,0xff,0x10); //Enable the Fixed DVTOTAL & Last Line Lenghth Fucntion
  334.    
  335.    return 0;
  336. #else
  337. #if (SPREAD_SPECTRUM)
  338.     RTDSetBit(SPREAD_SPECTRUM_99,0x0f,(DCLK_SPRED_RANGE << 4));
  339.     if(TestSync(usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE]))    
  340.    return 2;
  341. if(Data[0] & 0x03)
  342. {
  343.        if(TestSync((Data[0] & 0x02) ? (usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE] - 1)
  344.                                 : (usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE] + 1)))   //Fine tune Dclk offset 
  345.           return 2;
  346.    else 
  347.    {
  348.           if(Data[0] & 0x03)
  349.      return 1; //frame sync fail!
  350.   else
  351.                  return 0;
  352.    }
  353.    
  354. }
  355. #else
  356.        return 0;   
  357. #endif
  358.        return 0;
  359. #endif
  360. }
  361. void Adjust_I_Code(void)
  362. {
  363.    // Calculate the IHF in KHz
  364.    ((unsigned int*)Data)[0] = 24576/usHsync; //Input Horizontal Frequency
  365.    //Formula: I_Correction = CE * 2 * Fav(253687) * 100 / IHF / 2^(I_Code - 34)
  366.    //Data[2] : I_Code = 14; I_Code[13] = 0;
  367.    ucI_Code = 14;
  368.    Data[2] = ((unsigned long)ucCE_Value * 50737400 / (unsigned long)((unsigned int*)Data)[0]) >> 20;
  369.    Data[3] = (I_Correction == 0) ? (ucPE_Level ? (Correct_Amount - ucP_Corr) : ((ucP_Corr >> 2) + 10)) : 
  370.                                          I_Correction;
  371.    while(1)
  372.    {
  373.    
  374.    if(Data[2] > Data[3])
  375.    {
  376.    Data[2] = Data[2] >> 1;
  377.    ucI_Code -= 1;
  378.    if(Data[2] <= Data[3])
  379.    break;
  380.    }
  381.    else
  382.    {
  383.    if((Data[2] << 1) > Data[3])
  384.    break;
  385.    else
  386.    {
  387.    Data[2] = Data[2] << 1;
  388.    ucI_Code += 1;
  389.    }
  390.    }
  391.    }
  392. //             ucDebug_Value1 = ucP_Corr;
  393.    
  394.        if((unsigned char)((unsigned int)Data[2]*3/2) <= Data[3]) // Judge if I_Code[13] set to 1 will more close to 155
  395.    {          
  396.              ucI_Code |= 0x80;
  397. //  ucDebug_Value2 = ((unsigned char)((unsigned int)Data[2]*3) >> 1);   
  398.    }
  399.    else
  400.    {
  401. //      ucDebug_Value2 = Data[2];   
  402. }
  403. }