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

📄 frame_sync.c

📁 液晶显示器程序代码
💻 C
字号:
#define __FRAMESYNC__

#include "Header\Frame_Sync.h"
#include "Header\Lcd_func.h"
#include "Header\Access.h"
#include "Header\Main_def.h"
#include "Header\Config.h"
#include "Header\Lcd_main.h"
#include "Header\LCD_OSD.h"



        /////////////////////////
        // Frame-Sync Detector //
        /////////////////////////
bit Frame_Sync_Detector(void)
{
        if (bPower_Status && bStable && MODE_NOSIGNAL != ucMode_Curr && MODE_NOSUPPORT != ucMode_Curr)
        {
            if (bFrameSync)
            {
                RTDRead(STATUS1_1F, 1, N_INC);
                ucStatus    |= (Data[0] >> 6);

				if(Data[0])
					RTDSetByte(STATUS1_1F,0x00);

                if (Data[0] & 0xc0)
                {
                    ucSyncErrorCnt  += 1;
#if (RTDDEBUG)
                    if (0xff > ucDebug)     ucDebug ++; 
#endif
                }

//#if (DISP_BIT == DISP_18BIT)
//                else if (Data[0] & 0x04)
//                {
//                    bDitherToggle   = !bDitherToggle;

//                    if (bDitherToggle)
//                    {
//                        bDitherTable    = !bDitherTable;
//                        WriteDither(bDitherTable ? DITHER_1 : DITHER_2);
//                    }
//                }
//#endif

            }

            if (SYNC_FAIL_TIMES >= ucSyncErrorCnt)
            {
                RTDRead(STATUS0_01, 1, N_INC);
                ucStatus    |= (Data[0] & 0xfc);


				if(Data[0])
					RTDSetByte(STATUS0_01,0x00); //if some event happened, write once to clear status
               
                if (Data[0] & 0x60)     ucSyncErrorCnt  += (SYNC_FAIL_TIMES + 1);

                if (SOURCE_VGA == (stGUD1.INPUT_SOURCE & 0x07))
                {
                    if (Data[0] & 0x80)
                    {
                        ucSyncErrorCnt  += 1;
#if (RTDDEBUG)
                        if (0xff > ucDebug)     ucDebug ++;                       
#endif
                    }
                    else
                    {

#if(TUNE_APLL)

                  RTDSetBit(DV_TOTAL_STATUS_3D, 0x7f, 0x20); //Enable PE Max Measurement
				  Delay_Xms(1);
	              RTDRead(DV_TOTAL_STATUS_3D, 1, N_INC);
	              ucPE_Max = Data[0] & 0x1f;
				  if((ucPE_Max > 0x10) && (ucPE_Level == 0))
				  {
				      ucPE_Level = 1;
					  Adjust_I_Code();
                      if((ucI_Code & 0x80) == 0x80)
                         RTDSetBit(I_CODE_MB_CA,0xdf,0x20);  //Set the I_Code[13] to 1;
                      else
                         RTDSetBit(I_CODE_MB_CA,0xdf,0x00);  //Set the I_Code[13] to 0;
                      
                      ucI_Code = ucI_Code & 0x7f;
	                  RTDSetByte(I_CODE_LB_C9,0x1c | ((ucI_Code & 0x07) << 5));
	                  RTDSetBit(I_CODE_MB_CA,0xfc,0x04 | ((ucI_Code & 0x18) >> 3));

					  RTDSetBit(DV_TOTAL_STATUS_3D, 0xdf, 0x00);//Disable PE Max Measurement
                      RTDSetByte(DV_TOTAL_STATUS_3D,0x40); //clear PE Max value
					  ucPE_Max = 0;
				  }
				  
#endif
                    }
                }
            }

            if (SYNC_FAIL_TIMES < ucSyncErrorCnt)
            {
                Reset_Mode();

                Set_Task(STATE_MODECHANGE);     // Notify Task State Machine

                bNotify_Timer0_Int  = 0;

                return _TRUE;
                //continue;                       // leave current iteration.
            }

            if (bNotify_Timer0_Int && MODE_DETECT_FREQ == ucModeCnt)
            {
                if (ucSyncErrorCnt)     ucSyncErrorCnt  -= 1;

            }
        }
        return _FALSE;
}

/////////////////////////////////////////////////////////////////////////////////
// FrameSync fine-tune routines
/////////////////////////////////////////////////////////////////////////////////
void AbortSync(void)
{
    Data[0] = 5;
    Data[1] = Y_INC;
    Data[2] = DH_TOTAL_22;
    Data[3] = (unsigned char)usDH_Total;
    Data[4] = (unsigned char)(usDH_Total >> 8);
    Data[5] = 0;
    RTDWrite(Data);

    RTDSetBit(DV_TOTAL_H_2E, 0x07, 0x00);
}

unsigned char TestSync(unsigned int offset)     // 0 - Success; Otherwise - Fail
{

	RTDSetByte(DCLK_OFFSET_LSB_9A,(unsigned char)offset);
	RTDSetBit(DCLK_OFFSET_MSB_9B,0xf0,(unsigned char)((offset >> 8) & 0x0f) | 0x20);

    //RTDSetBit(DV_TOTAL_H_2E, 0x07, fine & 0xf8);

    Wait_For_Event(EVENT_DVS);          // Wait for Frame End
    //Delay_Xms(10);

	RTDSetByte(STATUS0_01,0x00);

    Wait_For_Event(EVENT_DVS);          // Wait for Frame End

    //RTDSetByte(STATUS0_01,0x00);////
/*
    if (SOURCE_VGA != (stGUD1.INPUT_SOURCE & 0x07))
    {
        Wait_For_Event(EVENT_DVS);      // Wait for Frame End
    }
*/
    Wait_For_Event(EVENT_DVS);          // Wait for Frame End

	//RTDSetByte(STATUS0_01,0x00);////
	//Delay_Xms(10);

    RTDRead(STATUS0_01, 1, N_INC);      // Get status


	if(Data[0])
	    RTDSetByte(STATUS0_01,0x00);


    if (Data[0] & 0x60) // Mode Changed
    {
        AbortSync();
        return 1;
    }

    Data[0] &= 0x03;

    return 0;   // Success
}



//Returned value
// 0 : Succeed(Frame-sync settings returned in Data[3] and Data[4])
// 1 : Fail
// 2 : Abort
#define Offset_Step      32//16 //This value should better larger then 16
unsigned char Frame_Sync(void)
{
   unsigned int idata usBuffer,usDelta;
   unsigned char idata  ucFine,ucTemp=0;

#if(FIX_LAST_DHT)
   unsigned int idata usMax_Last_Line,usMin_Last_Line;
#endif



   RTDRead(DCLK_OFFSET_LSB_9A , 2, Y_INC);
   Data[2] = Data[1] & 0x0f;
   Data[3] = Data[0];
   usBuffer = ((unsigned int*)Data)[1];//get the DCLK offset
   //usDelta = ((unsigned int*)Data)[1];//get the DCLK offset
   usDelta = usBuffer;
//   ucFine = 0;

   if(((stGUD1.INPUT_SOURCE & 0x07) == SOURCE_VGA) || ((stGUD1.INPUT_SOURCE & 0x07) == SOURCE_DVI))
   {

   //while(usDelta < Offset_Step * 14) 
   while(usBuffer < (1228 + 14 * Offset_Step))
   //while(usBuffer < (1228 + 24 * Offset_Step))	//eric 0729 issue: dvi flash
   {
	   RTDRead(DPLL_M_D1,2,Y_INC);
	   RTDSetByte(DPLL_M_D1,Data[0]+1);
	   RTDSetByte(DPLL_N_D2,Data[1]);
//     Forster :
//     if the DCLK offset too small, then set the M_Code = M_Code + 1
//     And reculculate the offset
//     Original formula:
//     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
//     => new_offset = (2^15 + M*old_offset) / (M+1);
	   usBuffer = (unsigned int)((unsigned long)(32768 + (unsigned long)(Data[0] + 2) * usBuffer)/(unsigned long)(Data[0] + 3));
	   //usBuffer = (32768 + (Data[0] + 2) * usDelta)/(Data[0] + 3);
	   usDelta = usBuffer;
       
   }


/*   //Below spend more code size
   ((unsigned int*)Data)[1] = 1228 + 14 * Offset_Step;

   if(usBuffer < ((unsigned int*)Data)[1])
   {
	   RTDRead(DPLL_M_D1,1,N_INC);
	   
	   ucFine =(unsigned char)((unsigned long)(Data[0] + 2) * (((unsigned int*)Data)[1] - usBuffer)/(unsigned long)(32768 - ((unsigned int*)Data)[1]));

	   usBuffer = (unsigned int)(((unsigned long)32768 * (ucFine + 1) + (unsigned long)(Data[0] + 2) * usBuffer)/(unsigned long)(Data[0] + 2 + (ucFine + 1)));

	   RTDSetByte(DPLL_M_D1,Data[0] + ucFine + 1);
	   RTDSetBit(DPLL_N_D2,0xf8,USER_MODE_NCODE - 2);
   }

   usDelta = usBuffer;
*/   
   usDelta -= 128; //Clk offset fine-tune
   }

   usBuffer = usDelta;
  

   for(ucFine =0;ucFine < 14;ucFine++)
   {
	   if (TestSync(usDelta))    return 2;

	   if(Data[0] & 0x03)
	   {
		   usDelta = (Data[0] & 0x02) ? usDelta - Offset_Step : usDelta + Offset_Step;
		   ucTemp += 1;
	   }
	   else if((Data[0] & 0x03) == 0)
		   break;
   }

   if(Data[0] & 0x03)
          return 1;   // Frame sync fail  
#if(SPREAD_SPECTRUM)
   else if(usDelta < usBuffer) //Get more margin of Framesync
   {
	   //usDelta -= 2;
	   if(TestSync(usDelta - 4))    return 2;

	   if(Data[0] & 0x03)
	       TestSync(usDelta);
	   else
	       usDelta -= 2;
	   
   }
   else//(usDelta > usBuffer) //Get more margin of Framesync
   {
	   //usDelta += 2;
	   if(TestSync(usDelta + 4))    return 2;

	   if(Data[0] & 0x03)
	       TestSync(usDelta);
	   else 
	       usDelta += 2;
   }
#endif   

//   ucDebug_Value0 = ucTemp;
#if(FIX_LAST_DHT)

   //Disable spread spectrum
#if(SPREAD_SPECTRUM)
    RTDSetBit(SPREAD_SPECTRUM_99,0x0f,0x00);
	RTDSetBit(DCLK_OFFSET_MSB_9B,0xff,0x20);
#endif
 
       //Read the last line information , read back data equal to half last line length
	   RTDRead(LAST_LINE_H_2C, 1, N_INC);
       usMax_Last_Line = (unsigned int)(Data[0] & 0xf8) << 2;

       RTDRead(LAST_LINE_L_26, 1, N_INC);
       usMax_Last_Line = usMax_Last_Line + (Data[0] / 8);
        
	    
	   	
	   //Read the last line information when frequency offset set one more step
	   RTDSetByte(DCLK_OFFSET_LSB_9A,(unsigned char)(usDelta + 1));
	   RTDSetBit(DCLK_OFFSET_MSB_9B,0xf0,(unsigned char)(((usDelta + 1) >> 8) & 0x07) | 0x20);

	   Wait_For_Event(EVENT_IVS);
	   Wait_For_Event(EVENT_IVS);

	   RTDRead(LAST_LINE_H_2C, 1, N_INC);
       usMin_Last_Line = (unsigned int)(Data[0] & 0xf8) << 2;
       RTDRead(LAST_LINE_L_26, 1, N_INC);
       usMin_Last_Line = usMin_Last_Line + (Data[0] / 8);

	    

	   //Calculate the difference of last line when increase one offset step
	   if(usMin_Last_Line < usMax_Last_Line)
		   usMin_Last_Line = usMax_Last_Line - usMin_Last_Line;
	   else
		   usMin_Last_Line = usDH_Total/2 - usMin_Last_Line + usMax_Last_Line;

	   if(FIX_LAST_DHT > usMax_Last_Line)
	   {
           if((FIX_LAST_DHT - usMax_Last_Line) > (usDH_Total / 4)) 
		   {   //decrease the last line, decrease the DClk
			   Data[0] = (unsigned int)(usMax_Last_Line + (usDH_Total / 2 - FIX_LAST_DHT)) / usMin_Last_Line;
			   usDelta = usDelta + Data[0];
		   }
		   else
		   {   //increase the last line, increase the DClk
			   Data[0] = (unsigned int)(FIX_LAST_DHT - usMax_Last_Line) / usMin_Last_Line; 
			   usDelta = usDelta - (Data[0] + 1);
		   }
	   }
	   else
	   {
		   if((usMax_Last_Line - FIX_LAST_DHT) > (usDH_Total / 4)) 
		   {   //increase the last line, increase the DClk
			   Data[0] = (unsigned int)(FIX_LAST_DHT + (usDH_Total / 2 - usMax_Last_Line)) / usMin_Last_Line;
			   usDelta = usDelta - (Data[0] + 1);
		   }
		   else
		   {   //decrease the last line, decrease the DClk
			   Data[0] = (usMax_Last_Line - FIX_LAST_DHT) / usMin_Last_Line; 
			   Data[11] = Data[0];
			   usDelta += Data[0];
			   
		   }
	   }


	 //Enable the apread spectrum again
#if (SPREAD_SPECTRUM)
    RTDSetBit(SPREAD_SPECTRUM_99,0x0f,(DCLK_SPRED_RANGE << 4));
    if(TestSync(usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE]))    
	   return 2;
	
	if(Data[0] & 0x03)
	{
       if(TestSync((Data[0] & 0x02) ? (usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE] - 1)
	                                : (usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE] + 1)))  //Fine tune Dclk offset 
	      return 2;
	   else
	   {
	          if(Data[0] & 0x03)
			     return 1; //frame sync fail!
			  else
                 return 0;
	   }
	}
#else
    if(TestSync(usDelta))    return 2;
#endif


	   RTDSetByte(FX_LST_LEN_L_59,(unsigned char)(FIX_LAST_DHT << 1));
	   RTDSetBit(FX_LST_LEN_H_5A,0x08,(unsigned char)((FIX_LAST_DHT >> 7) & 0x07));

        RTDRead(DV_ACT_END_34, 2, Y_INC);
        Data[2] = Data[1] & 0x07;
        Data[3] = Data[0];

        Data[4] = ((Data[1] & 0xf0) >> 4); //Measure result of last 16 line of DVTotal, including the un-complete last line
    
        // Get Output_Active Height
        ((unsigned int *)Data)[1]   = ((unsigned int *)Data)[1] - DV_ACT_STA_POS;

        // Original Idea :
        // DVTotal  = Output_Active_Line * (Input_Total_Line / Input_Active_Line) 
        usDelta = (unsigned long)usVsync * ((unsigned int *)Data)[1] / usIPV_ACT_LEN;	
        usDelta = (usDelta & 0xfff0 | Data[4]); 

		RTDSetByte(FIX_DVTOTAL_LSB_97,(unsigned char)usDelta);
		RTDSetByte(FIX_DVTOTAL_MSB_98,(unsigned char)((usDelta >> 8) & 0x07));

        RTDSetBit(SPREAD_SPECTRUM_99,0xfc,0x03); //Frequency Synthesis select N = 4
		RTDSetBit(DCLK_OFFSET_MSB_9B,0xff,0x20);

	
//	    RTDSetBit(FX_LST_LEN_H_5A,0xff,0x10); //Enable the Fixed DVTOTAL & Last Line Lenghth Fucntion
//	    RTDSetBit(FX_LST_LEN_H_5A,0xff,0x10); //Enable the Fixed DVTOTAL & Last Line Lenghth Fucntion
	   
	   return 0;
#else

#if (SPREAD_SPECTRUM)
    RTDSetBit(SPREAD_SPECTRUM_99,0x0f,(DCLK_SPRED_RANGE << 4));
    if(TestSync(usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE]))    
	   return 2;
	
	if(Data[0] & 0x03)
	{
       if(TestSync((Data[0] & 0x02) ? (usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE] - 1)
	                                : (usDelta + DCLK_OFFSET[DCLK_SPRED_RANGE] + 1)))   //Fine tune Dclk offset 
	   	      return 2;
	   else 
	   {
	          if(Data[0] & 0x03)
			     return 1; //frame sync fail!
			  else
                 return 0;
	   }
	   
	}
#else
       return 0;   
#endif
       return 0;
#endif

}




void Adjust_I_Code(void)
{
   // Calculate the IHF in KHz
	   ((unsigned int*)Data)[0] = 24576/usHsync; //Input Horizontal Frequency
	   //Formula: I_Correction = CE * 2 * Fav(253687) * 100 / IHF / 2^(I_Code - 34)
	   //Data[2] : I_Code = 14; I_Code[13] = 0;

	   ucI_Code = 14;
	   Data[2] = ((unsigned long)ucCE_Value * 50737400 / (unsigned long)((unsigned int*)Data)[0]) >> 20;
	   Data[3] = (I_Correction == 0) ? (ucPE_Level ? (Correct_Amount - ucP_Corr) : ((ucP_Corr >> 2) + 10)) : 
                                         I_Correction;

	   while(1)
	   {
		   
		   if(Data[2] > Data[3])
		   {
			   Data[2] = Data[2] >> 1;
			   ucI_Code -= 1;

			   if(Data[2] <= Data[3])
				   break;
		   }
		   else
		   {
			   if((Data[2] << 1) > Data[3])
				   break;
			   else
			   {
				   Data[2] = Data[2] << 1;
				   ucI_Code += 1;
			   }
		   }
	   }
//             ucDebug_Value1 = ucP_Corr;
	
	   
       if((unsigned char)((unsigned int)Data[2]*3/2) <= Data[3]) // Judge if I_Code[13] set to 1 will more close to 155
	   {	         
             ucI_Code |= 0x80;
//			 ucDebug_Value2 = ((unsigned char)((unsigned int)Data[2]*3) >> 1);   
	   }
	   else
	   {
//	   		 ucDebug_Value2 = Data[2];   
		}
		

}

⌨️ 快捷键说明

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