📄 mode_detect.c
字号:
RTDSetBit(SD_CTRL_70, 0xf9, VGA_ICLK_DELAY);
if (SOURCE_DVI == (stGUD1.INPUT_SOURCE & 0x07))
{
RTDSetBit(SD_CTRL_70, 0xf9, TMDS_ICLK_DELAY);
usIPH_ACT_STA = CAP_WIN[ucMode_Curr][1];
}
else
{
if (ucOption & 0x40)
{
// Only VGA-50Hz and VGA-60Hz mode will set bit 6 of ucMode_Curr to indicate 720-pixel capture width
// In these case, we should use 720 horizontal settings instead of 640 horizontal settings in table.
usADC_Clock = CAP_WIN[MODE_0720x0400x70HZ][0];
usIPH_ACT_STA = CAP_WIN[MODE_0720x0400x70HZ][1];
usIPH_ACT_WID = CAP_WIN[MODE_0720x0400x70HZ][2];
}
else
{
usADC_Clock = CAP_WIN[ucMode_Curr][0];
usIPH_ACT_STA = CAP_WIN[ucMode_Curr][1];
usIPH_ACT_WID = CAP_WIN[ucMode_Curr][2];
// Calculate pixel clock rate (round to MHz)
usDispLen = (unsigned long)24576 * usADC_Clock / ((unsigned long)usHsync * 500);
usDispLen = (usDispLen >> 1) + (usDispLen & 0x01);
// Use ADC to do H scale-down if pixel clock rate is over spec.
if (MAX_ADC_FREQ < usDispLen && MODE_USER1152x864 <= ucMode_Curr && MODE_USER1600x1200 >= ucMode_Curr)
{
usADC_Clock = ADC_SD_SET[ucMode_Curr - MODE_USER1152x864][0];
usIPH_ACT_STA = ADC_SD_SET[ucMode_Curr - MODE_USER1152x864][1];
usIPH_ACT_WID = ADC_SD_SET[ucMode_Curr - MODE_USER1152x864][2];
}
} //if (ucOption & 0x40)
// Calculate pixel clock rate (round to MHz)
usDispLen = (unsigned long)24576 * usADC_Clock / ((unsigned long)usHsync * 500);
usDispLen = (usDispLen >> 1) + (usDispLen & 0x01);
// To improve ADC performance ,when the data rate is slow, use single channel,otherwise, use dual channel
RTDSetBit(ADC_REG_CLK_EA,0xe0,(45 > usDispLen) ? 0x10 | (ADC_RED_PHASE_FT & 0x0c) |( ADC_BLUE_PHASE_FT & 0x03):
0x00 | (ADC_RED_PHASE_FT & 0x0c) |( ADC_BLUE_PHASE_FT & 0x03));
// To imporve the FIFO efficiency only when input data rate is slow, and display data rate is high.
// RTDSetBit(VGIP_CTRL_04, 0xe3, (40 > usDispLen) ? 0x14 : 0x00);
RTDSetBit(VGIP_CTRL_04, 0xf3, (60 > usDispLen) ? 0x08 : 0x00);
RTDSetByte(PE_CONTROL_3C, 0x00); // HSYNC positive/negtive tracking
RTDSetByte(ADC_FRAME_MODULE_EB,0x06);
// RTDSetByte(ADC_FRAME_MODULE_EB,(usIPH_ACT_WID == 1280) ? 0x04 : 0x00);
// Set ADC bandwidth to reduce high frequency noise
// RTDSetByte(ADC_REG_TEST_E9, (35 > usDispLen) ? 0x08 : (150 > usDispLen) ? 0x10 : 0x18);
#if(ADC_DEFFERENTIAL)
RTDSetBit(ADC_DIFF_MODE_EC,0xff,0x40); //Differential mode
#else
RTDSetBit(ADC_DIFF_MODE_EC,0xbf,0x00); //Single endded mode
#endif
RTDSetByte(ADC_REG_CUR_H_E8, 0x0d | (ADC_GREEN_PHASE_FT & 0x30));
RTDSetBit(ADC_FRAME_MODULE_EB,0xc7, ((ADC_RED_PHASE_FT & 0x10) << 1) | ((ADC_GREEN_PHASE_FT & 0x40) << 2)
|((ADC_BLUE_PHASE_FT & 0x04) << 1));
RTDSetBit(TMDS_CORRECTION_FF,0xff,0x04); //Enable the ADC digital filter
if(ucMode_Curr < MODE_1024x0768x70HZ)
RTDSetByte(ADC_REG_TEST_E9, 0x08);
else
RTDSetByte(ADC_REG_TEST_E9, 0x10);
// Get usIPV_ACT_LEN
if (MODE_UNDEFINED0 > ucMode_Curr)
{
// We've already decided usIPV_ACT_LEN in Detect_VGA_Mode() for undefined SU/SD mode.
// Only defined modes need to decide usIPV_ACT_LEN here.
usIPV_ACT_LEN = CAP_WIN[ucMode_Curr][4];
}
} //if (SOURCE_DVI == (stGUD1.INPUT_SOURCE & 0x07))
// Get standard usIPV_ACT_STA
RTDSetByte(IVS_DELAY_8C, PROGRAM_VDELAY);
usIPV_ACT_STA = CAP_WIN[ucMode_Curr][3] - PROGRAM_VDELAY - 1;
RTDSetByte(IHS_DELAY_8D, PROGRAM_HDELAY);
// usIPH_ACT_STA = usIPH_ACT_STA + CAPTURE_HDELAY - PROGRAM_HDELAY;
if(ucMode_Curr < MODE_0800x0600x75HZ)
Data[0] = 2;
else if(ucMode_Curr < MODE_1280x1024x75HZ)
Data[0] = 5;
else
Data[0] = 3;
// Data[0] = 5;
usIPH_ACT_STA = usIPH_ACT_STA + Data[0] - PROGRAM_HDELAY;
// Decide display length (height) and store to usDispLen
usDispLen = Mode_Preset[ucMode_Curr][2];
if (MODE_UNDEFINED0 == ucMode_Curr) // partical-screen scale-up mode
{
if (ucOption & 0x80) // partial-V
{
if (MIN_DV_TOTAL > (usVsync - 1))
usDispLen = (unsigned long)usIPV_ACT_LEN * MIN_DV_TOTAL / (usVsync - 1);
else
usDispLen = usIPV_ACT_LEN; // No V scale-up
}
}
else if (MODE_UNDEFINED1 == ucMode_Curr) // partial-screen scale-down mode
{
if (ucOption & 0x80) // partial-V
{
usDispLen = (unsigned long)usIPV_ACT_LEN * MIN_DV_TOTAL / (usVsync - 1);
}
} //if (MODE_UNDEFINED0 == ucMode_Curr) // partical-screen scale-up mode
if (Mode_Preset[ucMode_Curr][2] < usDispLen) usDispLen = Mode_Preset[ucMode_Curr][2];
// This F/W do not support V scale-up(or bypass) and H scale-down simultaneously
if (usDispLen >= usIPV_ACT_LEN && Mode_Preset[ucMode_Curr][1] < usIPH_ACT_WID)
{
usIPH_ACT_WID = Mode_Preset[ucMode_Curr][1];
}
if (usDispLen > usIPV_ACT_LEN) ucOption |= 0x01; // bit 0 : V scale-up
if (usDispLen < usIPV_ACT_LEN) ucOption |= 0x02; // bit 1 : V scale-down
if (Mode_Preset[ucMode_Curr][1] > usIPH_ACT_WID) ucOption |= 0x04; // bit 2 : H scale-up
if (Mode_Preset[ucMode_Curr][1] < usIPH_ACT_WID) ucOption |= 0x08; // bit 3 : H scale-down
// Set capture window
Data[0] = 11;
Data[1] = Y_INC;
Data[2] = IPH_ACT_STA_06;
Data[3] = (unsigned char)usIPH_ACT_STA;
Data[4] = (unsigned char)(usIPH_ACT_STA >> 8);
Data[5] = (unsigned char)usIPH_ACT_WID;
Data[6] = (unsigned char)(usIPH_ACT_WID >> 8);
Data[7] = (unsigned char)usIPV_ACT_STA;
Data[8] = (unsigned char)(usIPV_ACT_STA >> 8);
Data[9] = (unsigned char)usIPV_ACT_LEN;
Data[10] = (unsigned char)(usIPV_ACT_LEN >> 8);
Data[11] = 0;
RTDWrite(Data);
// Set window size before scale-up
Data[0] = 7;
Data[1] = Y_INC;
Data[2] = DRW_BSU_40;
if (ucOption & 0x08)
{
// H scale-down
Data[3] = (unsigned char)Mode_Preset[ucMode_Curr][1];
Data[4] = (unsigned char)(Mode_Preset[ucMode_Curr][1] >> 8);
}
else
{
// No H scale-down
Data[3] = Data[5]; // (unsigned char)usIPH_ACT_WID;
Data[4] = Data[6]; // (unsigned char)(usIPH_ACT_WID >> 8);
}
if (ucOption & 0x02)
{
// V scale-down
Data[5] = (unsigned char)usDispLen;
Data[6] = (unsigned char)(usDispLen >> 8);
}
else
{
// No V scale-down
Data[5] = Data[9]; // (unsigned char)usIPV_ACT_LEN;
Data[6] = Data[10]; // (unsigned char)(usIPV_ACT_LEN >> 8);
}
Data[7] = 0;
RTDWrite(Data);
// Config scaling
if (ucOption & 0x0a)
RTDSetBit(SD_CTRL_70, 0xff, 0x01); // Turn on scale-down
else
RTDSetBit(SD_CTRL_70, 0xfe, 0x00); // Turn off scale-down
if (ucOption & 0x01)
RTDSetBit(SCALE_CTRL_15, 0xff, 0x02); // Turn on V scale-up
else
RTDSetBit(SCALE_CTRL_15, 0xfd, 0x00); // Turn off V scale-up
if (ucOption & 0x04)
RTDSetBit(SCALE_CTRL_15, 0xff, 0x01); // Turn on H scale-up
else
RTDSetBit(SCALE_CTRL_15, 0xfe, 0x00); // Turn off H scale-up
// Set scale-down coefficient
Data[0] = 7;
Data[1] = Y_INC;
Data[2] = H_SCALE_DL_71;
if (ucOption & 0x08) // H scale-down
{
// Data[12~15]
((unsigned long *)Data)[3] = (unsigned long)256 * 4096 * usIPH_ACT_WID / Mode_Preset[ucMode_Curr][1];
// Data[4~5]
((unsigned int *)Data)[2] = (((unsigned long *)Data)[3] >> 8) + 2;
// H scale-down factor is stored in Data[4] (high-byte) and Data[5] (low-byte)
Data[3] = Data[5];
RTDSetBit(VGIP_CTRL_04, 0xff, 0x40); // Enable H scale-down compensation
}
else
{
Data[3] = 0x00;
Data[4] = 0x10;
RTDSetBit(VGIP_CTRL_04, 0xbf, 0x00); // Diable H scale-down compensation
}
if (ucOption & 0x02) // V scale-down
{
// Data[12~15]
((unsigned long *)Data)[3] = (unsigned long)256 * 4096 * usIPV_ACT_LEN / usDispLen;
// Data[6~7]
((unsigned int *)Data)[3] = (((unsigned long *)Data)[3] >> 8);
if (0 == Data[15]) ((unsigned int *)Data)[3] = ((unsigned int *)Data)[3] - 1;
// V scale-down factor is stored in Data[6] (high-byte) and Data[7] (low-byte)
Data[5] = Data[7];
RTDSetBit(VGIP_CTRL_04, 0xff, 0x80); // Enable V scale-down compensation
}
else
{
Data[5] = 0x00;
Data[6] = 0x10;
RTDSetBit(VGIP_CTRL_04, 0x7f, 0x00); // Diable V scale-down compensation
}
Data[7] = 0;
RTDWrite(Data);
// Set scale-up coefficient
Data[0] = 8;
Data[1] = Y_INC;
Data[2] = HOR_SCA_16;
if (ucOption & 0x04) // H scale-up
{
// Data[12~15]
((unsigned long *)Data)[3] = (unsigned long)2 * 262144 * usIPH_ACT_WID / Mode_Preset[ucMode_Curr][1];
((unsigned long *)Data)[3] = ((((unsigned long *)Data)[3] >> 1) + (((unsigned long *)Data)[3] & 0x01)) << 6;
Data[3] = Data[14];
Data[4] = Data[13];
Data[7] = Data[15];
}
else
{
Data[3] = 0xff;
Data[4] = 0xff;
Data[7] = 0;
}
if (ucOption & 0x01) // V scale-up
{
// Data[12~15]
((unsigned long *)Data)[3] = (unsigned long)2 * 262144 * usIPV_ACT_LEN / usDispLen;
((unsigned long *)Data)[3] = ((((unsigned long *)Data)[3] >> 1) + (((unsigned long *)Data)[3] & 0x01)) << 6;
Data[5] = Data[14]; //anson 05_0315
// Data[5] = 0x90;
Data[6] = Data[13];
// Data[6] = 0xc0;
Data[7] = Data[7] | (Data[15] >> 4);
}
else
{
Data[5] = 0xff;
Data[6] = 0xff;
}
Data[8] = 0;
RTDWrite(Data);
// Set RTD display
// Switch to FrameSync 1 mode and diable display
RTDSetByte(VDIS_CTRL_20, 0x28 | DISP_BIT | DISPLAY_PORT);
Data[0] = 5;
Data[1] = Y_INC;
#if (DISP_ALIGN)
Data[2] = DH_ACT_STA_27;
// DH_ACT_STA store in Data[4~5] (H~L)
((unsigned int *)Data)[2] = (unsigned int)DH_ACT_END_POS - Mode_Preset[ucMode_Curr][1];
Data[3] = Data[5];
#else
Data[2] = DH_ACT_END_29;
// DH_ACT_STA store in Data[4~5] (H~L)
((unsigned int *)Data)[2] = (unsigned int)DH_ACT_STA_POS + Mode_Preset[ucMode_Curr][1];
Data[3] = Data[5];
#endif
Data[5] = 5;
Data[6] = Y_INC;
Data[7] = DV_ACT_END_34;
// DV_ACT_END store in Data[10~11] (H~L)
((unsigned int *)Data)[5] = (unsigned int)DV_ACT_STA_POS + usDispLen;
Data[8] = Data[11];
Data[9] = Data[10];
Data[10] = 0;
RTDWrite(Data);
// Get standard DH_TOTAL
usDH_Total = Mode_Preset[ucMode_Curr][0];
// Switch to FrameSync 1 mode and enable display
// if (PANEL_OFF == bPANEL_PWR)
if (_OFF == bPanel_Status)
RTDSetByte(VDIS_CTRL_20, 0x29 | DISP_BIT | DISPLAY_PORT);
else
RTDSetByte(VDIS_CTRL_20, 0x2b | DISP_BIT | DISPLAY_PORT);
Set_Dclk(usDispLen);
//usDH_Total = usDH_Total - 2;
// Set DH_TOTAL
Data[0] = 5;
Data[1] = Y_INC;
Data[2] = DH_TOTAL_22;
Data[3] = (unsigned char)(usDH_Total - 2);
Data[4] = (unsigned char)((usDH_Total - 2) >> 8);
Data[5] = 0;
RTDWrite(Data);
//Calculate DV_TOTAL
if((ucOption & 0x01) || (ucOption & 0x02)) // V scale up or scale down
{
#if(DISP_SIZE == DISP_800x600)
usDV_Total = (unsigned long)usVsync * 600 / (unsigned long)usIPV_ACT_LEN + 64;
#endif
#if(DISP_SIZE == DISP_1024x768)
usDV_Total = (unsigned long)usVsync * 768 / (unsigned long)usIPV_ACT_LEN + 64;
#endif
#if(DISP_SIZE == DISP_1280x1024)
usDV_Total = (unsigned long)usVsync * 1024 / (unsigned long)usIPV_ACT_LEN + 64;
#endif
}
else
usDV_Total = usVsync + 64;
//Set DV_TOTAL
Data[0] = 5;
Data[1] = Y_INC;
Data[2] = DV_TOTAL_2D;
Data[3] = (unsigned char)usDV_Total;
Data[4] = (unsigned char)((usDV_Total >> 8) & 0x07);
Data[5] = 0;
RTDWrite(Data);
// Calculate suitable IVS to DVS delay
// CR[38] : IVS to DVS delay in IHS lines
// CR[1E] : IVS to DVS delay in ICLK * 16
//((unsigned int *)Data)[0] = (unsigned long)64 * DV_ACT_STA_POS * usIPV_ACT_LEN / usDispLen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -