📄 lcd_auto.c
字号:
#define __AUTO__
#include "Header\INCLUDE.H"
unsigned char Auto_Config(void)
{
unsigned char Result, Noise, Color, Curr_PosH, Curr_PosV, Curr_Clock, Curr_Phase;
unsigned int Curr_HIAS;
// Enter Auto Progress
bAutoInProgress = 1;
bPowerDownWhenAuto = 0;
// Save current settings
Curr_HIAS = usIPH_ACT_STA;
Curr_PosH = stMUD.H_POSITION;
Curr_PosV = stMUD.V_POSITION;
Curr_Clock = stMUD.CLOCK;
Curr_Phase = stMUD.PHASE;
// IVS delay will increase when V position is larger than ucV_Max_Margin.
// Large IVS delay may cause auto-function fail.
if (ucV_Max_Margin < stMUD.V_POSITION)
{
stMUD.V_POSITION = ucV_Max_Margin - 1;
Set_V_Position();
}
// Clock and H-position limitation for low resolution
if (800 >= usIPH_ACT_WID)
{
usIPH_ACT_STA = usIPH_ACT_STA + 50;
ucH_Min_Margin = (128 - 100) + 50;
if ((128 - 50) > stMUD.CLOCK || (128 + 50) < stMUD.CLOCK) stMUD.CLOCK = 128;
}
stMUD.H_POSITION = 128;
Set_H_Position();
Set_Clock();
// Clear the HW auto status to prevent some un-expected event happened
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
RTDSetByte(HW_AUTO_PHASE_9E, 0x00);
RTDSetByte(STATUS0_01, 0x00); // Clear status
RTDSetByte(STATUS1_1F, 0x00); // Clear status
// Do auto-config under reasonable ADC settings
RTDCodeW(ADC_DEFAULT);
// Get boundary of image
Result = Min_Noise_Margin();
Noise = Data[0];
if (ERROR_SUCCEED != Result)
{
stMUD.CLOCK = Curr_Clock;
stMUD.PHASE = Curr_Phase;
stMUD.H_POSITION = Curr_PosH;
stMUD.V_POSITION = Curr_PosV;
}
else
{
// Select color for rough search
Color = FindColor();
if (COLORS_FAIL == Color)
{
Result = ERROR_INPUT;
stMUD.CLOCK = Curr_Clock;
stMUD.PHASE = Curr_Phase;
stMUD.H_POSITION = Curr_PosH;
stMUD.V_POSITION = Curr_PosV;
}
else
{
if (MODE_0640x0350x70HZ <= ucMode_Curr && MODE_0720x0400x70HZ >= ucMode_Curr)
{
// Restore default clock instead of doing auto-clock for DOS/BIOS mode
stMUD.CLOCK = 128;
Set_Clock();
Result = ERROR_SUCCEED;
}
else
{
Result = Auto_Clock_Do(Noise, Color);
}
if (ERROR_SUCCEED != Result)
{
stMUD.CLOCK = Curr_Clock;
stMUD.PHASE = Curr_Phase;
stMUD.H_POSITION = Curr_PosH;
stMUD.V_POSITION = Curr_PosV;
}
else
{
Result = Auto_Phase_Do(Noise, Color);
if (ERROR_SUCCEED != Result)
{
stMUD.PHASE = Curr_Phase;
stMUD.H_POSITION = Curr_PosH;
stMUD.V_POSITION = Curr_PosV;
}
else
{
Result = Auto_Position_Do(Noise);
if (ERROR_SUCCEED != Result)
{
stMUD.H_POSITION = Curr_PosH;
stMUD.V_POSITION = Curr_PosV;
}
}
}
}
}
// Restore settings
usIPH_ACT_STA = Curr_HIAS;
ucH_Min_Margin = 128 - 100;
if (ERROR_SUCCEED == Result)
{
Set_H_Position();
Save_Auto_Result();
}
else if (ERROR_INPUT != Result)
{
Set_Clock();
Set_Phase(stMUD.PHASE);
Set_H_Position();
Set_V_Position();
}
RTDSetByte(STATUS0_01, 0x00); // Clear status
RTDSetByte(STATUS1_1F, 0x00); // Clear status
// Restore ADC Gain/Offset
SetADC_GainOffset();
// Exit Auto Progress
bAutoInProgress = 0;
return bPowerDownWhenAuto ? ERROR_SUCCEED : Result;
}
unsigned char Auto_Balance(void)
{
unsigned char Result, Curr_PosV, Curr_Gain;
bAutoInProgress = 1;
Curr_PosV = stMUD.V_POSITION; // Save current stMUD.V_POSITION
if (ucV_Max_Margin < stMUD.V_POSITION)
{
stMUD.V_POSITION = ucV_Max_Margin - 1;
Set_V_Position();
}
// Restore ADC gain/offset to default
Curr_Gain = stGUD0.CONTRAST;
stGUD0.CONTRAST = 50;
SetADC_GainOffset();
// Do ADC gain/offset adjust
Result = Tune_Balance();
if (ERROR_SUCCEED == Result)
{
stGUD0.CONTRAST = 50;
/*
stGUD0.RTD_R_CONTRAST = 50;
stGUD0.RTD_G_CONTRAST = 50;
stGUD0.RTD_B_CONTRAST = 50;
stGUD0.RTD_R_BRIGHT = 50;
stGUD0.RTD_G_BRIGHT = 50;
stGUD0.RTD_B_BRIGHT = 50;
*/
Set_Bright_Contrast();
SetADC_GainOffset();
Save_GUD0();
Save_GUD2();
}
else
{
// Restore ADC Gain/Offset
stGUD0.CONTRAST = Curr_Gain;
Load_GUD2();
SetADC_GainOffset();
}
// Restore vertical position
stMUD.V_POSITION = Curr_PosV;
Set_V_Position();
bAutoInProgress = 0;
return Result;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Sub-Routine called by Auto_Config() and Auto_Balance()
///////////////////////////////////////////////////////////////////////////////////////////
void Wait_Finish(void)
{
unsigned char Wait_Time_Cnt, IVS_Event;
RTDSetByte(STATUS0_01, 0x00); // Clear status
RTDSetByte(STATUS1_1F, 0x00); // Clear status
Wait_Time_Cnt = 50; // Auto timeout 50ms
IVS_Event = 25; // IVS timeout 25ms
do
{
Delay_Xms(1);
RTDRead(STATUS1_1F, 1, N_INC); // Read Status
if (Data[0] & EVENT_IVS)
{
RTDSetByte(STATUS1_1F, 0x00); // Clear status
IVS_Event = 25;
}
else
{
IVS_Event = IVS_Event - 1;
}
if (0 == IVS_Event || (Data[0] & (EVENT_UNDERFLOW | EVENT_OVERFLOW)))
{
Data[0] = ERROR_INPUT;
return;
}
RTDRead(AUTO_ADJ_CTRL_7F, 1, N_INC);
}
while ((Data[0] & 0x01) && (--Wait_Time_Cnt) && (!bPowerDownWhenAuto));
RTDRead(STATUS0_01, 1, N_INC); // Read Status
RTDSetByte(STATUS0_01, 0x00); // Clear Status
// Return non-zero value in Data[0] if :
// 1. IVS or IHS changed
// 2. Auto-Phase Tracking timeout
Data[0] = ((Data[0] & 0x63) || (0 == Wait_Time_Cnt) || bPowerDownWhenAuto) ? ERROR_INPUT : ERROR_SUCCEED;
}
#if (HARDWARE_AUTO)
unsigned char Wait_For_IVS(void)
{
unsigned char ucTimeOut = 25;
RTDSetByte(STATUS1_1F, 0x00);
do
{
Delay_Xms(1);
RTDRead(STATUS1_1F, 1, N_INC);
Data[0] &= (EVENT_IVS | EVENT_UNDERFLOW | EVENT_OVERFLOW);
}
while ((0 == Data[0]) && (--ucTimeOut));
return Data[0];
}
#endif
unsigned char Measure_PositionV(unsigned char NM_V)
{
unsigned int usLBound, usRBound;
RTDRead(MEAS_HI_51, 0x02, Y_INC);
Data[2] = Data[1] & 0x0f;
Data[3] = Data[0];
usRBound = usADC_Clock + (unsigned int)stMUD.CLOCK - 128;
usLBound = (unsigned long)usRBound * ((unsigned int *)Data)[1] / usHsync;
// Original formula :
// usRBound = usRBound - 2 - (PROGRAM_HDELAY - MEASURE_HDEALY) - (stMUD.H_POSITION - ucH_Min_Margin);
// usLBound = usLBound + 20 - (PROGRAM_HDELAY - MEASURE_HDEALY) - (stMUD.H_POSITION - ucH_Min_Margin);
usRBound = usRBound - 2 + MEASURE_HDEALY - PROGRAM_HDELAY + ucH_Min_Margin - stMUD.H_POSITION;
usLBound = usLBound + 20 + ucH_Min_Margin + MEASURE_HDEALY;
usLBound = usLBound > ((unsigned int)stMUD.H_POSITION + PROGRAM_HDELAY) ? (usLBound - PROGRAM_HDELAY - stMUD.H_POSITION) : 1;
NM_V = NM_V & 0xfc;
Data[0] = 6;
Data[1] = Y_INC;
Data[2] = H_BND_STA_L_75;
Data[3] = (unsigned char)usLBound;
Data[4] = (unsigned char)usRBound;
Data[5] = ((unsigned char)(usLBound >> 4) & 0x70) | ((unsigned char)(usRBound >> 8) & 0x0f);
Data[6] = 8;
Data[7] = Y_INC;
Data[8] = MARGIN_R_7B;
Data[9] = NM_V;
Data[10] = NM_V | PIXEL_1;
Data[11] = NM_V;
Data[12] = 0x00;
Data[13] = 0x01;
Data[14] = 0;
RTDWrite(Data);
Wait_Finish();
if (ERROR_SUCCEED != Data[0]) return Data[0];
RTDRead(VER_START_80, 4, Y_INC);
// Translate byte order : RTD little indian -> 8051 big indian
Data[6] = Data[1] & 0x0f;
Data[7] = Data[0];
Data[8] = Data[3] & 0x0f;
Data[9] = Data[2];
// V Start/End should subtract 1
usVer_Start = ((unsigned int *)Data)[3] ? ((unsigned int *)Data)[3] - 1 : 0;
usVer_End = ((unsigned int *)Data)[4] ? ((unsigned int *)Data)[4] - 1 : 0;
// Check all black
if (0x0000 == usVer_End) return ERROR_ABORT;
// To prevent from noise induced by VSYNC
if (9 > usVer_Start + PROGRAM_VDELAY)
{
((unsigned int *)Data)[3] = 9 - PROGRAM_VDELAY;
usVer_Start = usVer_End - usIPV_ACT_LEN + 1;
}
else if (usVer_End > (usVer_Start + usIPV_ACT_LEN - 1))
{
usVer_End = usVer_Start + usIPV_ACT_LEN - 1;
((unsigned int *)Data)[4] = usVer_End;
}
// Update auto-tracking window vertical range
Data[0] = 6;
Data[1] = Y_INC;
Data[2] = V_BND_STA_L_78;
Data[3] = Data[7];
Data[4] = Data[9];
Data[5] = (Data[6] << 4) + Data[8];
Data[6] = 0;
RTDWrite(Data);
return ERROR_SUCCEED;
}
unsigned char Measure_PositionH(unsigned char NM_H)
{
unsigned int usLBound, usRBound;
RTDRead(MEAS_HI_51, 2, Y_INC);
Data[2] = Data[1] & 0x0f;
Data[3] = Data[0];
usRBound = usADC_Clock + (unsigned int)stMUD.CLOCK - 128; // Totol Clock Number
usLBound = (unsigned long)usRBound * ((unsigned int *)Data)[1] / usHsync; // Clock number in HSYNC pulse
RTDRead(IHS_DELAY_8D, 1, N_INC);
//usRBound = usRBound - 2 + MEASURE_HDEALY - PROGRAM_HDELAY - stMUD.H_POSITION + ucH_Min_Margin;
usRBound = (usRBound + MEASURE_HDEALY - Data[0]) - 2;
//usLBound = usLBound + 20 + MEASURE_HDEALY - Data[0];
usLBound = (usLBound + 20 + MEASURE_HDEALY) > Data[0] ? (usLBound + 20 + MEASURE_HDEALY) - Data[0] : 0x0001;
NM_H = NM_H & 0xfc;
Data[0] = 6;
Data[1] = Y_INC;
Data[2] = H_BND_STA_L_75;
Data[3] = (unsigned char)usLBound;
Data[4] = (unsigned char)usRBound;
Data[5] = ((unsigned char)(usLBound >> 4) & 0x70) | ((unsigned char)(usRBound >> 8) & 0x0f);
Data[6] = 8;
Data[7] = Y_INC;
Data[8] = MARGIN_R_7B;
Data[9] = NM_H;
Data[10] = NM_H;
Data[11] = NM_H;
Data[12] = 0x00;
Data[13] = 0x01;
Data[14] = 0;
RTDWrite(Data);
Wait_Finish();
if (ERROR_SUCCEED != Data[0]) return Data[0];
RTDRead(HOR_START_84, 4, Y_INC);
// Translate byte order : RTD little indian -> 8051 big indian
Data[4] = Data[3] & 0x0f;
Data[5] = Data[2];
Data[2] = Data[1] & 0x0f;
Data[3] = Data[0];
if (0x07FF <= ((unsigned int *)Data)[1]) return ERROR_ABORT;
// In low speed capture, there are 3-clock extra capture delay.
RTDRead(VGIP_CTRL_04, 1, N_INC);
NM_H = (0x08 == (Data[0] & 0x0c)) ? 0x03 : 0x00;
//usH_Start = ((unsigned int *)Data)[1] - (MEAS_H_STA_OFFSET - NM_H);
//usH_End = ((unsigned int *)Data)[1] - (MEAS_H_END_OFFSET - NM_H);
usH_Start = (((unsigned int *)Data)[1] + NM_H) > MEAS_H_STA_OFFSET
? (((unsigned int *)Data)[1] + NM_H) - MEAS_H_STA_OFFSET : 0x0000;
usH_End = (((unsigned int *)Data)[2] + NM_H) > MEAS_H_END_OFFSET
? (((unsigned int *)Data)[2] + NM_H) - MEAS_H_END_OFFSET : 0x0fff;
return ERROR_SUCCEED;
}
// Issac : Only for Auto Balance
unsigned char Measure_PositionN(unsigned char NM)
{
unsigned char Result;
Result = Measure_PositionV(NM);
if (ERROR_SUCCEED != Result) return Result;
Result = Measure_PositionH(NM);
if (ERROR_SUCCEED != Result) return Result;
RTDRead(VER_START_80, 4, Y_INC);
// Translate byte order : RTD little indian -> 8051 big indian
Data[6] = Data[1] & 0x0f;
Data[7] = Data[0];
Data[8] = Data[3] & 0x0f;
Data[9] = Data[2];
usVer_Start = ((unsigned int *)Data)[3];
usVer_End = ((unsigned int *)Data)[4];
RTDRead(HOR_START_84, 4, Y_INC);
// Translate byte order : RTD little indian -> 8051 big indian
Data[4] = Data[3] & 0x0f;
Data[5] = Data[2];
Data[2] = Data[1] & 0x0f;
Data[3] = Data[0];
usH_Start = ((unsigned int *)Data)[1];
usH_End = ((unsigned int *)Data)[2];
return ERROR_SUCCEED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -