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

📄 mode_detect.c

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

#include "Header\INCLUDE.H"


/////////////////////////////////////////////////////////
//-------------------  Mode Detector  -----------------//
/////////////////////////////////////////////////////////
bit Input_Mode_Detector(void)
{
#if (VIDEO_CHIP == VDC_NONE)

    // Issac :
    // Mode detection must finish within 20ms * (MODE_DETECT_FREQ + 1)
    // If mode detection is over before time-out, we should read the
    // detection result right now.
    RTDRead(SYNC_POR_4C, 0x01, N_INC);

    if (0 == (Data[0] & 0x02))      ucModeCnt   = 0;

#else

    if ((SOURCE_VGA == (stGUD1.INPUT_SOURCE & 0x07)) || (SOURCE_DVI == (stGUD1.INPUT_SOURCE & 0x07)))
    {
        RTDRead(SYNC_POR_4C, 0x01, N_INC);

        if (0 == (Data[0] & 0x02))      ucModeCnt   = 0;
    }

#endif

    if (ucModeCnt)
    {                  
        ucModeCnt   -= 1;
    }
    else
    {
        ucModeCnt   = MODE_DETECT_FREQ;

#if (SOURCE_AUTO_SCAN) 
        Source_Auto_Scan();
#else
        Mode_Detector();
#endif				

    }

    return bStable ? _FALSE : _TRUE;
}

void Mode_Detector(void)
{
    switch (stGUD1.INPUT_SOURCE & 0x07)
    {
    case SOURCE_VGA :
    case SOURCE_DVI :

#if (NOSUPPORT_RESET == _TRUE)

        if (MODE_NOSIGNAL == ucMode_Curr)
            Detect_Input_Mode();
        else
            Check_Input_Mode();
#else
        if (MODE_NOSIGNAL == ucMode_Curr || MODE_NOSUPPORT == ucMode_Curr)
            Detect_Input_Mode();
        else
            Check_Input_Mode();
#endif

        break;

    default :

#if (VIDEO_CHIP != VDC_NONE)

        if (MODE_NOSIGNAL == ucMode_Curr)
            Detect_Video_Mode();        // Set default polarity 
        else
            Check_Video_Mode();         // Set polarity after measure
#else
        ucMode_Curr = MODE_NOSIGNAL;
#endif

        break;
    }
    
    Measure_Mode();     // Measure mode-timing
}

void Measure_Mode(void)
{
    RTDSetByte(SYNC_CTRL_4A, 0x00);

    switch (stGUD1.INPUT_SOURCE & 0x07)
    {
    case SOURCE_VGA :
        RTDSetByte(SYNC_POR_4C, (SYNC_SS == ucSync_Type) ? 0x02 : 0x22);
        break;
    case SOURCE_DVI :
#if (TMDS_ENABLE)
        if (0 == ucTMDS_SEARCH_COUNTER)
        {
            RTDCodeW(TMDS_MANUAL_ON);
            ucTMDS_SEARCH_COUNTER  = 0x08;
        }        
        ucTMDS_SEARCH_COUNTER -= 0x01;
#endif
        RTDSetByte(SYNC_POR_4C, 0x02);       
        break;
    default :
        RTDSetByte(SYNC_POR_4C, 0x02);
        break;
    }	
}

unsigned char VGA_Mode_Search(unsigned int HS_Pulse)
{
    unsigned char   ucMode_Temp, m;
    
    // Issac :
    // Data[0] is just for mode decision between 720x350 and 640x350.
    // HSYNC pulse in VGA 640x350 is longer than VGA 720x350.
    Data[0]     = HS_Pulse * 12 / usHsync;

    ucMode_Temp = MODE_NOSUPPORT;

    // Search for Standard Mode
    m   = MODE_1600x1200x60HZ;
    do
    {
        // Issac
        // Because VGA_Mode[][] table is based on 24.576MHz crystal,
        // we have to translate the table if not using 24.576MHz crystal
        if ((usHsync > ((unsigned long)VGA_Mode[m][0] * RTD_XTAL / XTAL24576K)) && (usHsync < ((unsigned long)VGA_Mode[m][1] * RTD_XTAL / XTAL24576K)))
        {   
            if ((usVsync >= VGA_Mode[m][2]) && (usVsync <= VGA_Mode[m][3]))
            {
                if (MODE_1280x1024x75HZ == m)
                {
                    // Issac : I disabled SUN 1024-76, because it is easy to confused.

                    //if (0 == (bVpole | bHpole))     m   = MODE_1280x1024x76HZ;  // SUN 1024-76
                }                            
                else if (MODE_1024x0768x75HZ == m)
                {
                    if (0 == (bVpole | bHpole))     m   = MODE_1024x0768x74HZ;  // MAC768-75
                }         
                else if (MODE_0640x0480x60HZ == m && bVpole != bHpole)
                {
                    // MODE_VGA350x60Hz         : 640x350 60Hz
                    // MODE_VGA350x60Hz | 0x40  : 720x350 60Hz
                    // MODE_VGA400x60Hz         : 640x400 60Hz
                    // MODE_VGA400x60Hz | 0x40  : 720x400 60Hz
                    if (bHpole)
                        m   = Data[0] ? MODE_VGA350x60Hz : MODE_VGA350x60Hz | 0x40;
                    else
                        m   = (stGUD1.FUNCTION & 0x10) ? MODE_VGA400x60Hz : MODE_VGA400x60Hz | 0x40;
			  }
			  else if (MODE_0640x0480x50HZ == m && bVpole != bHpole)
			  {
				  // MODE_VGA350x50Hz         : 640x350 50Hz
				  // MODE_VGA350x50Hz | 0x40  : 720x350 50Hz
				  // MODE_VGA400x50Hz         : 640x400 50Hz
				  // MODE_VGA400x50Hz | 0x40  : 720x400 50Hz
				  if (bHpole)
					  m   = Data[0] ? MODE_VGA350x50Hz : MODE_VGA350x50Hz | 0x40;
				  else
					  m   = (stGUD1.FUNCTION & 0x10) ? MODE_VGA400x50Hz : MODE_VGA400x50Hz | 0x40;
			  }
			  else if (MODE_0720x0400x85HZ == m)
			  {
				  if (1 == bHpole && 0 == bVpole)
					  m   = MODE_0640x0350x85HZ;
				  else if (stGUD1.FUNCTION & 0x10)    
					  m   = MODE_0640x0400x85HZ;
			  }
			  else if (MODE_0720x0400x70HZ == m)
			  {
				  if (1 == bHpole && 0 == bVpole)
					  m   = Data[0] ? MODE_0640x0350x70HZ : MODE_0720x0350x70HZ;
				  else if (stGUD1.FUNCTION & 0x10)
					  m   = MODE_0640x0400x70HZ;
			  }
			  else if (MODE_1024x0768x59HZ == m)
			  {
				  if (HS_Pulse > 45)
					  m = MODE_1024x0768x60HZ;
			  }
			  else if (MODE_1024x0768x60HZ == m)
			  {
				  if (HS_Pulse <= 45)
					  m = MODE_1024x0768x59HZ;					   
			  }

			  ucMode_Temp     = m;
		  }
	  }
  }
  while ((0 != --m) && (MODE_NOSUPPORT == ucMode_Temp));
  
  // Search for User Mode
  if (MODE_NOSUPPORT == ucMode_Temp)
  {
      usIPV_ACT_LEN   = 0;

      m   = MODE_USER1600x1200;
	  do
	  {
		  if ((usVsync >= VGA_Mode[m][2]) && (usVsync <= VGA_Mode[m][3]))
		  {
			  usIPV_ACT_LEN   = CAP_WIN[m][4];
			  
			  if ((usHsync >= VGA_Mode[m][0]) && (usHsync <= VGA_Mode[m][1]))
			  {
				  ucMode_Temp     = m;    // Support User Mode
			  }
		  }
	  }
	  while ((MODE_USER720x400 <= --m) && (MODE_NOSUPPORT == ucMode_Temp));
  }

  return ucMode_Temp;
}


#if (PARTIAL_DISP)

unsigned char Partial_Display(void)
{
    unsigned char ucMode_Temp;

    if (DISP_LEN < usIPV_ACT_LEN)   // V Scale-down
    {
        // Estimate display clock rate for full screen
        // DCLK = (XTAL / usHsync) * DCLK per display line * (display image lines / input image lines)
        ((unsigned int *)Data)[0]   = (unsigned long)(RTD_XTAL / 10) * Mode_Preset[MODE_UNDEFINED1][0] * DISP_LEN 
            / ((unsigned long)100 * usIPV_ACT_LEN * usHsync);

        if (MAX_DCLK < ((unsigned int *)Data)[0])
        {
            // If clock rate for full-screen display is too high, we can try partial-V display.
            // Estimate clock for partial-V display
            // DCLK = (XTAL / usHsync) * DCLK per display line * (min. display total lines / input total lines)
            ((unsigned int *)Data)[1]   = (unsigned long)(RTD_XTAL / 10) * Mode_Preset[MODE_UNDEFINED1][0] * MIN_DV_TOTAL
                / ((unsigned long)100 * (usVsync - 1) * usHsync);

            if (MAX_DCLK < ((unsigned int *)Data)[1])
            {
                // Decrease usIPV_ACT_LEN to DISP_LEN and go further to check if it can be displayed.
                usIPV_ACT_LEN   = DISP_LEN;
            }
            else
            {
                ucMode_Temp     = MODE_UNDEFINED1 | 0x80;   // Scale-down and partial-V display
            }
        }
        else
            ucMode_Temp     = MODE_UNDEFINED1;              // Scale-down and full-V display
    }
	
	if (DISP_LEN >= usIPV_ACT_LEN)  // V Scale-up
	{
        ((unsigned int *)Data)[0]   = (unsigned long)(RTD_XTAL / 10) * Mode_Preset[MODE_UNDEFINED0][0] * DISP_LEN 
            / ((unsigned long)100 * usIPV_ACT_LEN * usHsync);

        if (MAX_DCLK < ((unsigned int *)Data)[0])
        {
            if (MIN_DV_TOTAL >= (usVsync - 1))
            {
                ((unsigned int *)Data)[1]   = (unsigned long)(RTD_XTAL / 10) * Mode_Preset[MODE_UNDEFINED0][0] 
                                            * MIN_DV_TOTAL / ((unsigned long)100 * (usVsync - 1) * usHsync);
            }
            else
            {
                ((unsigned int *)Data)[1]   = (unsigned long)(RTD_XTAL / 10) * Mode_Preset[MODE_UNDEFINED0][0]
                                            / ((unsigned long)100 * usHsync);
            }

            if (MAX_DCLK < ((unsigned int *)Data)[1])   
                ucMode_Temp = MODE_NOSUPPORT;           // Cannot display
            else
                ucMode_Temp = MODE_UNDEFINED0 | 0x80;   // Scale-up and partial-V display
        }
        else
            ucMode_Temp = MODE_UNDEFINED0;              // Scale-up and full-V display
    }
    
    return ucMode_Temp;
}

#endif



void Sync_Type_Switch(void)
{
    switch (ucSync_Type)
    {
    case SYNC_SS :  // SS->SOG
        RTDCodeW(VGA_SET_SOG);
        ucSync_Type = SYNC_SOG;
        break;
    case SYNC_CS :  // CS->SS
        RTDCodeW(VGA_SET_SS);
        ucSync_Type = SYNC_SS;
        break;
    default :       // SOG->CS
        RTDCodeW(VGA_SET_CS);
        ucSync_Type = SYNC_CS;
        break;
    }
}

void Sync_Type_Confirm(void)
{    
    unsigned char m;
             
    if (SYNC_SS == ucSync_Type)
    {
        // To prevent from mistaking CS (with VS) for SS, we check SYNC type once when finding a mode in SS.
        
        RTDSetByte(SYNC_CTRL_4B, 0x55);
        RTDSetByte(SYNC_POR_4C, 0x22);

        m   = (MODE_DETECT_FREQ + 1) * 20;
        do
        {   
            Delay_Xms(1);
            RTDRead(SYNC_POR_4C, 0x05, Y_INC);
        }
        while ((Data[0] & 0x02) && (--m));
        
        Data[5] = Data[3];
        Data[4] = Data[4] & 0x87;
        Data[3] = Data[1];
        Data[2] = Data[2] & 0x8f;

        if ((0 == ((unsigned int *)Data)[1]) || (0x07ff <= ((unsigned int *)Data)[1]) ||
            (0 == ((unsigned int *)Data)[2]) || (0x07ff <= ((unsigned int *)Data)[2]) ||
            (0 == m))
        {
            ucSync_Type = SYNC_SS;

            RTDSetByte(SYNC_CTRL_4B, 0x14);
        }
        else
        {
            ucSync_Type = SYNC_CS;

            RTDCodeW(VGA_SET_CS);
        }
        
        // Issac : Code below is not necessary.
        /*
        unsigned char   ucTemp;
      
        RTDRead(VGIP_SIGINV_05, 0x01, N_INC);
        ucTemp  = Data[0] & 0x20;

        RTDSetByte(SYNC_CTRL_4B, 0x55);
        RTDSetByte(SYNC_POR_4C, 0x22);

        m   = (MODE_DETECT_FREQ + 1) * 20;
        do
        {   
            Delay_Xms(1);
            RTDRead(SYNC_POR_4C, 0x05, Y_INC);
        }
        while ((Data[0] & 0x02) && (--m));

        if (m)
        {
            if (0 == ((Data[0] & 0x04) ^ (ucTemp >> 3)))
            {
                // In composite mode, if HSYNC polarity is negative, it must be inverted for period measure
                RTDSetBit(VGIP_SIGINV_05, 0xdf, ucTemp ^ 0x20);

                RTDSetByte(SYNC_POR_4C, 0x22);

                m   = (MODE_DETECT_FREQ + 1) * 20;
                do
                {   
                    Delay_Xms(1);
                    RTDRead(SYNC_POR_4C, 0x05, Y_INC);
                }
                while ((Data[0] & 0x02) && (--m));
            }
        }
        
        Data[5] = Data[3];
        Data[4] = Data[4] & 0x87;
        Data[3] = Data[1];
        Data[2] = Data[2] & 0x8f;

⌨️ 快捷键说明

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