📄 mode_detect.c
字号:
// To improve ADC performance ,when the data rate is slow, use single channel,otherwise, use dual channel
RTDSetBit(ADC_REG_CLK_EA, 0xef, (45 > usDispLen) ? 0x10 : 0x00);
// To imporve the FIFO efficiency only when input data rate is slow, and display data rate is high.
RTDSetBit(VGIP_CTRL_04, 0xf3, (60 > usDispLen) ? 0x08 : 0x00);
// Set ADC bandwidth to reduce high frequency noise
RTDSetByte(ADC_REG_TEST_E9, (68 > usDispLen) ? 0x08 : 0x10);
RTDSetByte(PE_CONTROL_3C, 0x00); // HSYNC positive/negtive tracking
#if (ADC_DEFFERENTIAL)
RTDSetBit(ADC_DIFF_MODE_EC, 0xff, 0x40); // Differential mode
#else
RTDSetBit(ADC_DIFF_MODE_EC, 0xbf, 0x00); // Single endded mode
#endif
// Fine-tune R/G/B delay
RTDSetByte(ADC_REG_CUR_H_E8, 0x0d | ((ADC_GREEN_PHASE_FT & 0x03) << 4));
RTDSetBit(ADC_REG_CLK_EA, 0xe0, ((ADC_RED_PHASE_FT & 0x03) << 2) | (ADC_BLUE_PHASE_FT & 0x03));
RTDSetBit(ADC_FRAME_MODULE_EB, 0xc7,
((ADC_RED_PHASE_FT & 0x04) << 3) | ((ADC_GREEN_PHASE_FT & 0x04) << 2) |((ADC_BLUE_PHASE_FT & 0x04) << 1));
// Enable the ADC frame-modulation and digital filter
RTDSetBit(ADC_FRAME_MODULE_EB, 0xf8, 0x06);
RTDSetBit(TMDS_CORRECTION_FF, 0xff, 0x04);
// 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];
}
}
// 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 + ucDelay - PROGRAM_HDELAY;
// Decide display length (height) and store to usDispLen
usDispLen = Mode_Preset[ucMode_Curr][2];
// For partial display
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_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
// Disable low-speed input function when doing scaling down
if (ucOption & 0x0a) RTDSetBit(VGIP_CTRL_04, 0xf7, 0x00);
// 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] & 0xc0;
}
else
{
Data[3] = 0xff;
Data[4] = 0xff;
Data[7] = 0xc0;
}
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];
Data[6] = Data[13];
Data[7] = Data[7] | ((Data[15] & 0xc0) >> 4);
}
else
{
Data[5] = 0xff;
Data[6] = 0xff;
Data[7] = Data[7] | 0x0c;
}
Data[8] = 0;
RTDWrite(Data);
// Set RTD display
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] = 0;
RTDWrite(Data);
// Issac :
// I modified these codes in order to make partial display in vertical center position.
ucDelay = ((unsigned int)DISP_LEN - usDispLen) >> 1;
// DV_ACT_STA/DV_ACT_END store in Data[4~7] (H~L)
((unsigned int *)Data)[2] = (unsigned int)DV_ACT_STA_POS + ucDelay;
((unsigned int *)Data)[3] = ((unsigned int *)Data)[2] + usDispLen;
Data[0] = 7;
Data[1] = Y_INC;
Data[2] = DV_ACT_STA_32;
Data[3] = Data[5];
Data[5] = Data[7];
Data[7] = 0;
RTDWrite(Data);
// Get standard DH_TOTAL
usDH_Total = Mode_Preset[ucMode_Curr][0];
// 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);
// Disable spread spectrum
RTDSetBit(SPREAD_SPECTRUM_99, 0x0f, 0x00);
RTDSetBit(DCLK_OFFSET_MSB_9B, 0xff, 0x20);
// Calculate and set display clock frequency
((unsigned long *)Data)[0] = (unsigned long)RTD_XTAL * usDH_Total / usHsync * usDispLen / usIPV_ACT_LEN;
Set_DPLL(((unsigned long *)Data)[0]);
// Calculate DV_TOTAL setting for watchdog
// Save result in Data[4][5]
((unsigned int *)Data)[2]
= (ucOption & 0x03) ? (unsigned long)usVsync * usDispLen / (unsigned long)usIPV_ACT_LEN + 64 : usVsync + 64;
Data[0] = 5;
Data[1] = Y_INC;
Data[2] = DV_TOTAL_2D;
Data[3] = Data[5];
Data[4] = Data[4] & 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;
((unsigned int *)Data)[0] = (unsigned long)64 * (DV_ACT_STA_POS + ucDelay) * usIPV_ACT_LEN / usDispLen;
if (ucOption & 0x01)
{
if (800 >= usIPH_ACT_WID)
Calculate_IVS2DVS_Delay(2, 8, ((unsigned int*)Data)[0]); // V scale-up. Target 2.5~2.6 IHS delay
else if (1280 > usIPH_ACT_WID)
Calculate_IVS2DVS_Delay(2, 6, ((unsigned int*)Data)[0]); // V scale-up. Target 2.5~2.6 IHS delay
else
Calculate_IVS2DVS_Delay(2, 4, ((unsigned int*)Data)[0]); // V scale-up. Target 2.5~2.6 IHS delay
}
else
{
#if (FULL_LINE_BUFFER)
Calculate_IVS2DVS_Delay(3, 8, ((unsigned int*)Data)[0]); // V no scale-up. Target 3.8~4.0 IHS delay
#else
if (ucOption & 0x02)
{
// V scale-down
if (1280 > usIPH_ACT_WID)
Calculate_IVS2DVS_Delay(2, 6, ((unsigned int*)Data)[0]); // V scale-down. Target 2.5~2.6 IHS delay
else
Calculate_IVS2DVS_Delay(2, 4, ((unsigned int*)Data)[0]); // V scale-down. Target 2.5~2.6 IHS delay
}
else
{
Calculate_IVS2DVS_Delay(1, 9, ((unsigned int*)Data)[0]); // V no scaling. Target 1.9 IHS delay
}
#endif
}
#if (FULL_LINE_BUFFER)
// Turn on full-line buffer when no V scale-up
RTDSetBit(OP_CRC_CTRL_68, 0xfc, (ucOption & 0x01) ? 0x00 : 0x02);
#else
RTDSetBit(OP_CRC_CTRL_68, 0xfc, 0x00);
#endif
// Switch to FrameSync 1 mode and diable display
RTDSetByte(VDIS_CTRL_20, 0x28 | DISP_BIT | DISPLAY_PORT | DHS_MASK);
// Input Run Enable
RTDSetBit(VGIP_CTRL_04, 0xff, 0x01);
// Enable display timing
if (_ON == bPanel_Status)
RTDSetByte(VDIS_CTRL_20, 0x2b | DISP_BIT | DISPLAY_PORT | DHS_MASK);
else
RTDSetByte(VDIS_CTRL_20, 0x29 | DISP_BIT | DISPLAY_PORT | DHS_MASK);
// Clear Status
RTDSetByte(STATUS0_01, 0x00);
RTDSetByte(STATUS1_1F, 0x00);
}
void Display_VGA_Set(void)
{
unsigned char Wait_Time_Cnt;
Initial_Mode();
Sharpness();
if ((usIPH_ACT_WID == 1280) && (DISP_SIZE == DISP_1280x1024) && (stGUD1.FILTER == 0x02))
{
// Issac
// It is just for using horizontal sharpness function to improve phase in 1:1 display.
// Turn on H scale-up
RTDSetBit(SCALE_CTRL_15, 0xff, 0x01);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -