📄 mode_detect.c
字号:
PowerDown_ADC();
// Set user's ADC gain and offset settings
SetADC_GainOffset();
Set_Gamma();
Set_Dithering();
Set_Bright_Contrast();
// Read mode default settings from EEPROM
Load_MUD(ucMode_Curr);
// Read auto result from EEPROM
I2CRead(ADDR_EROM2, (ucMode_Curr - 1) << 2, 0x03);
// Check auto result range
ucAUTO_HPOS = (128 + 100) < Data[0] ? 128 : (128 - 100) > Data[0] ? 128 : Data[0];
ucAUTO_VPOS = (128 + 32) < Data[1] ? 128 : (128 - 32) > Data[1] ? 128 : Data[1];
ucAUTO_SCLK = (128 + 100) < Data[2] ? 128 : (128 - 100) > Data[2] ? 128 : Data[2];
// Check Clock within adjustable range
if (28 > stMUD.CLOCK || 228 < stMUD.CLOCK)
stMUD.CLOCK = 128;
if (ucAUTO_SCLK > ((unsigned int)stMUD.CLOCK + 50) || ((unsigned int)ucAUTO_SCLK + 50) < stMUD.CLOCK)
stMUD.CLOCK = ucAUTO_SCLK;
// For jitter adjust
ucPE_Level = 0;
ucI_Code = 0;
// Set Clock
Set_Clock();
// Calculate the P correction and I correction according to the CE value
Delay_Xms(6);
if (0 == ucCE_Value)
{
RTDRead(I_CODE_MB_CA, 1, N_INC);
RTDSetByte(I_CODE_MB_CA, 0x0d);
Delay_Xms(4);
RTDRead(PLL_CALIBRATION_CE, 1, N_INC);
// Prevent the read back data equal to 0
if (0 == Data[0]) Data[0] = 38;
ucP_Corr = (unsigned char)((unsigned int)(Data[0] * 200) >> (29 - P_Code_Value));
ucCE_Value = Data[0]; //CE value
}
Adjust_I_Code();
// Set clock again after adjust I code
Set_Clock();
// Setup margin for adjusting H position
usIPH_ACT_STA -= 100;
ucH_Max_Margin = 128 + 100;
ucH_Min_Margin = 128 - 100;
// Check H-Position
if (28 > stMUD.H_POSITION || 228 < stMUD.H_POSITION)
stMUD.H_POSITION = 128;
if (((unsigned int)ucAUTO_HPOS + 50) < stMUD.H_POSITION || ucAUTO_HPOS > ((unsigned int)stMUD.H_POSITION + 50))
stMUD.H_POSITION = ucAUTO_HPOS;
// Update H-Position
Set_H_Position();
// Check Phase
stMUD.PHASE &= 0x7c; // Phase 0~31
// Update Phase
Set_Phase(stMUD.PHASE);
// Start auto-tracking function once
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x01);
Delay_Xms(40);
// Force to stop auto-tracking function
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
Delay_Xms(40);
// Measure actual number of scan line in each frame
RTDCodeW(MEASURE_IVS);
Wait_Time_Cnt = 50; // Tracking timeout 50ms
do
{
Delay_Xms(1);
RTDRead(AUTO_ADJ_CTRL_7F, 0x01, N_INC);
}
while ((Data[0] & 0x01) && (--Wait_Time_Cnt));
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
if (Wait_Time_Cnt)
{
RTDRead(VER_START_80, 0x04, Y_INC);
Data[0] = Data[3] & 0x0f;
Data[1] = Data[2];
usVer_End = usVsync < ((unsigned int *)Data)[0] ? ((unsigned int *)Data)[0] : usVsync;
}
else
{
usVer_End = usVsync;
}
// Update to reasonable usIPV_ACT_STA for user mode
if (MODE_USER720x400 <= ucMode_Curr)
{
((unsigned int *)Data)[0] = usVer_End - VGA_Mode[ucMode_Curr][2];
if ((254 - 8) < ((unsigned int *)Data)[0] + ucDV_Delay) ((unsigned int *)Data)[0] = (254 - 8) - ucDV_Delay;
usIPV_ACT_STA += ((unsigned int *)Data)[0];
ucDV_Delay += ((unsigned int *)Data)[0];
}
// Set the ucV_Min_Margin/ucV_Max_Margin
ucV_Min_Margin = (128 < usIPV_ACT_STA) ? 0 : 128 - usIPV_ACT_STA + 1;
if ((128 - 50) > ucV_Min_Margin) ucV_Min_Margin = 128 - 50;
((unsigned int *)Data)[0] = (usVer_End + 128 - PROGRAM_VDELAY) - (usIPV_ACT_STA + usIPV_ACT_LEN);
ucV_Max_Margin = (((unsigned int *)Data)[0] > 0x00ff) ? 0xff : ((unsigned int *)Data)[0];
// Check ucV_Min_Margin/ucV_Max_Margin :
// ucDV_Delay can only range from 0 to 254
// Original Formula :
// 128 - ucV_Min_Margin >= ucDV_Delay
// ucV_Max_Margin - 128 >= 254 - ucDV_Delay
if ((unsigned int)128 > ((unsigned int)ucV_Min_Margin + ucDV_Delay)) ucV_Min_Margin = 128 - ucDV_Delay;
if ((unsigned int)382 < ((unsigned int)ucV_Max_Margin + ucDV_Delay)) ucV_Max_Margin = 382 - ucDV_Delay;
if ((128 + 50) < ucV_Max_Margin) ucV_Max_Margin = 128 + 50;
// Check auto result for V position
if ((ucV_Min_Margin + 1) > ucAUTO_VPOS)
ucAUTO_VPOS = 128;
else if (ucV_Max_Margin < ucAUTO_VPOS)
ucAUTO_VPOS = 128;
// Check V-Position
if (ucV_Min_Margin > stMUD.V_POSITION)
stMUD.V_POSITION = ucV_Min_Margin;
if (stMUD.V_POSITION > ((unsigned int)ucAUTO_VPOS << 1) - ucV_Min_Margin)
stMUD.V_POSITION = ((unsigned int)ucAUTO_VPOS << 1) - ucV_Min_Margin;
// Update V-Position
Set_V_Position();
// Re-calculate actual refresh rate
((unsigned long *)Data)[0] = (unsigned long)usHsync * usVer_End;
ucRefresh = ((unsigned long)RTD_XTAL * 1000 * 2) / ((unsigned long *)Data)[0];
ucRefresh = (ucRefresh & 0x01) ? ((ucRefresh + 1) >> 1) : (ucRefresh >> 1);
if (V_OVERSPEC_FREQ < ucRefresh || H_OVERSPEC_FREQ < (unsigned int)RTD_XTAL / usHsync) bOverSpec = _TRUE;
Data[0] = Frame_Sync();
if (1 == Data[0])
{
// Fail and retry once
Delay_Xms(10);
Data[0] = Frame_Sync();
}
#if (FORCE_DISP)
bFrameSync = Data[0] ? 0 : 1; // 0 : fail, 1 : pass
#else
bFrameSync = 1;
#endif
RTDSetBit(VDIS_CTRL_20, 0x7f, 0x20 | DHS_MASK); // Background display
RTDSetByte(STATUS0_01, 0x00); // Clear Status
RTDSetByte(STATUS1_1F, 0x00); // Clear Status
}
void Display_DVI_Set(void)
{
#if (TMDS_ENABLE)
unsigned char Wait_Time_Cnt;
Initial_Mode();
// Set the ucV_Min_Margin/ucV_Max_Margin
ucV_Min_Margin = (128 < usIPV_ACT_STA) ? 0 : 128 - usIPV_ACT_STA + 1;
// Use Data[8],Data[9] as a temporary 16-bit variable.
((unsigned int *)Data)[4] = (usVsync + 128 - 2) - (usIPV_ACT_STA + usIPV_ACT_LEN);
ucV_Max_Margin = (0x00ff < ((unsigned int *)Data)[4]) ? 0xff : ((unsigned int *)Data)[4];
// Check ucV_Min_Margin/ucV_Max_Margin :
// ucDV_Delay can only range from 0 to 254
// Original Formula :
// 128 - ucV_Min_Margin <= ucDV_Delay
// ucV_Max_Margin - 128 <= 254 - ucDV_Delay
if ((unsigned int)128 > ((unsigned int)ucV_Min_Margin + ucDV_Delay)) ucV_Min_Margin = 128 - ucDV_Delay;
if ((unsigned int)382 < ((unsigned int)ucV_Max_Margin + ucDV_Delay)) ucV_Max_Margin = 382 - ucDV_Delay;
// Read mode default settings from 24C04
Load_MUD(ucMode_Curr);
Set_Gamma();
Set_Dithering();
Set_Bright_Contrast();
Sharpness();
// Issac :
// RTD controller can support both digital mode and analog mode to capture input image data.
// In digital mode, input image data is captured according to input data enable (IDEN) signal;
// In analog mode, input image data is captured according to capture window settings;
// Although can support both of them, I always use analog mode to capture input image in this F/W.
// Because RTD controller can measure the position and size of IDEN signal, we can just set our
// capture window to be the same size and position as IDEN.
Data[0] = 14;
Data[1] = Y_INC;
Data[2] = H_BND_STA_L_75;
Data[3] = 0x02;
Data[4] = usADC_Clock - 2;
Data[5] = (usADC_Clock - 2) >> 8;
Data[6] = 0x02;
Data[7] = usVsync - 2;
Data[8] = (usVsync - 2) >> 8;
Data[9] = 0;
Data[10] = 0;
Data[11] = 0;
Data[12] = 0;
Data[13] = 0x81; // Measure IDEN position
Data[14] = 0;
RTDWrite(Data);
Wait_Time_Cnt = 60; // Tracking timeout 60ms
do
{
Delay_Xms(1);
RTDRead(AUTO_ADJ_CTRL_7F, 0x01, N_INC);
}
while ((Data[0] & 0x01) && (--Wait_Time_Cnt));
if (0 == Wait_Time_Cnt)
{
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
Reset_Mode();
}
else
{
// Read IDEN position information
RTDRead(VER_START_80, 0x08, Y_INC);
// IDEN horizontal Start
usIPH_ACT_STA = (unsigned int)Data[4] + ((unsigned int)Data[5] << 8) - 2;
// IDEN vertical Start
((unsigned int *)Data)[0] = (unsigned int)Data[0] + ((unsigned int)Data[1] << 8) - 1;
if (((unsigned int *)Data)[0] > (usIPV_ACT_STA + ucV_Max_Margin - 0x80))
{
/*
((unsigned int *)Data)[1] = (usVsync + 128 - 2) - (usIPV_ACT_STA + usIPV_ACT_LEN); // Actual V max. Margin
ucDV_Delay = (unsigned char)((unsigned int)ucDV_Delay + ucV_Max_Margin - 0x80);
usIPV_ACT_STA = usIPV_ACT_STA + ucV_Max_Margin - 0x80;
if (ucV_Max_Margin < ((unsigned int *)Data)[1])
{
// We have to increase IVS delay to fix ucV_Max_Margin
if ((((unsigned int *)Data)[1] - ucV_Max_Margin) >= (((unsigned int *)Data)[0] - usIPV_ACT_STA))
((unsigned int *)Data)[1] = ((unsigned int *)Data)[0] - usIPV_ACT_STA + PROGRAM_VDELAY;
else
((unsigned int *)Data)[1] = usIPV_ACT_STA + ((unsigned int *)Data)[1] - ucV_Max_Margin + PROGRAM_VDELAY;
if (126 < ((unsigned int *)Data)[1]) ((unsigned int *)Data)[1] = 126;
RTDSetByte(IVS_DELAY_8C, 0x80 | ((unsigned int *)Data)[1]);
}
*/
ucDV_Delay = (unsigned char)((unsigned int)ucDV_Delay + ucV_Max_Margin - 0x80);
usIPV_ACT_STA = usIPV_ACT_STA + ucV_Max_Margin - 0x80;
RTDSetByte(IVS_DELAY_8C, ((unsigned int *)Data)[0] - usIPV_ACT_STA + PROGRAM_VDELAY);
}
else if (((unsigned int *)Data)[0] < (usIPV_ACT_STA + ucV_Min_Margin - 0x80))
{
/*
ucDV_Delay = (unsigned char)((unsigned int)ucDV_Delay + ucV_Min_Margin - 0x80);
usIPV_ACT_STA = usIPV_ACT_STA + ucV_Min_Margin - 0x80;
((unsigned int *)Data)[1] = usIPV_ACT_STA - ((unsigned int *)Data)[0];
// We have to decrease IVS delay to fix ucV_Min_Margin
if (PROGRAM_VDELAY <= ((unsigned int *)Data)[1])
RTDSetByte(IVS_DELAY_8C, 0x00);
else
RTDSetByte(IVS_DELAY_8C, 0x80 | (PROGRAM_VDELAY - ((unsigned int *)Data)[1]));
*/
ucDV_Delay = (unsigned char)((unsigned int)ucDV_Delay + ucV_Min_Margin - 0x80);
usIPV_ACT_STA = usIPV_ACT_STA + ucV_Min_Margin - 0x80;
((unsigned int *)Data)[1] = usIPV_ACT_STA - ((unsigned int *)Data)[0];
if (PROGRAM_VDELAY <= ((unsigned int *)Data)[1])
RTDSetByte(IVS_DELAY_8C, 0x00);
else
RTDSetByte(IVS_DELAY_8C, PROGRAM_VDELAY - ((unsigned int *)Data)[1]);
}
else
{
ucDV_Delay = ((unsigned int *)Data)[0] + ucDV_Delay - usIPV_ACT_STA ;
usIPV_ACT_STA = ((unsigned int *)Data)[0];
}
//if TMDS error correction enable, then compensate the IPH_ACT_STA offset.
RTDRead(TMDS_CORRECTION_FF, 0x01, N_INC);
if (Data[0] & 0x03) usIPH_ACT_STA -= 14;
Data[0] = 5;
Data[1] = Y_INC;
Data[2] = IPH_ACT_STA_06;
Data[3] = (unsigned char)(usIPH_ACT_STA & 0x00ff);
Data[4] = (unsigned char)((usIPH_ACT_STA >> 8) & 0x00ff);
Data[5] = 5;
Data[6] = Y_INC;
Data[7] = IPV_ACT_STA_0A;
Data[8] = (unsigned char)(usIPV_ACT_STA & 0x00ff);
Data[9] = (unsigned char)((usIPV_ACT_STA >> 8) & 0x00ff);
Data[10] = 4;
Data[11] = N_INC;
Data[12] = IV_DV_LINES_38;
Data[13] = ucDV_Delay;
Data[14] = 0;
RTDWrite(Data);
Wait_For_Event(EVENT_DVS);
Data[0] = Frame_Sync();
if (1 == Data[0])
{
Data[0] = Frame_Sync(); // Fail. Try again
}
#if (FORCE_DISP)
bFrameSync = Data[0] ? 0 : 1; // 0 : fail, 1 : pass
#else
bFrameSync = 1;
#endif
RTDSetBit(VDIS_CTRL_20, 0x7f, 0x20 | DHS_MASK); // Background display
}
#endif
RTDSetByte(STATUS0_01, 0x00); // Clear Status
RTDSetByte(STATUS1_1F, 0x00); // Clear Status
}
#if (VIDEO_CHIP != VDC_NONE)
/////////////////////////////////////////////////////////
//----------------- Display VIDEO Mode ----------------//
/////////////////////////////////////////////////////////
void Set_Video_Mode(void)
{
#if (VIDEO_CHIP == VDC_SAA7114 || VIDEO_CHIP == VDC_SAA7115 || VIDEO_CHIP == VDC_SAA7118)
I2CWrite(V_DISABLE);
I2CWrite(VIDEO_ALL);
I2CWrite((ucAV_Mode & 0x02) ? VIDEO_50 : VIDEO_60);
#endif
RTDCodeW((ucAV_Mode & 0x02) ? RTD_VIDEO_50 : RTD_VIDEO_60);
// if (PANEL_OFF == MCU_ReadPanelPower())
if (_OFF == bPanel_Status)
{
RTDSetByte(VDIS_SIGINV_21, 0x00 | DISP_EO_SWAP | DISP_RB_SWAP | DISP_ML_SWAP); // DHS, DVS, DEN, DCLK MUST NOT be inverted.
RTDSetBit(VDIS_CTRL_20, 0xfd, 0x01); // DHS, DVS, DEN, DCLK and data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -