📄 mode_detect.c
字号:
#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 + -