📄 lcd_auto.c
字号:
unsigned char Min_Noise_Margin(void)
{
unsigned char Result, Noise;
unsigned int Curr_StartH, Curr_EndH;
Result = Measure_PositionV(VERTICAL_MARGIN);
if (ERROR_SUCCEED != Result) return Result;
if (0 == usVer_Start)
{
Result = Measure_PositionV(VERTICAL_MARGIN + 0x20);
if (ERROR_SUCCEED != Result) return Result;
}
Noise = 0x00;
Result = Measure_PositionH(Noise);
if (ERROR_SUCCEED != Result) return Result;
Curr_StartH = usH_Start; // Save H start position at noise margin = 0
Curr_EndH = usH_End; // Save H end position at noise margin = 0
do
{
Noise = Noise + 0x10;
Result = Measure_PositionH(Noise);
if (ERROR_SUCCEED != Result) return Result;
if (Curr_StartH >= usH_Start)
{
Curr_StartH = usH_Start;
}
else if (0x08 < (usH_Start - Curr_StartH))
{
break; // A large gap of H start position is found.
}
}
while (0x90 > Noise);
if (0x80 < Noise) return ERROR_ABORT;
while (1)
{
Curr_StartH = usH_Start;
Curr_EndH = usH_End;
Result = Measure_PositionH(Noise + 0x20);
if (ERROR_SUCCEED != Result) return Result;
// We got noise margin with stable horizontal start/end position.
if ((Curr_EndH - Curr_StartH) == (usH_End - usH_Start) || (Curr_EndH - Curr_StartH) >= (usH_End - usH_Start + 3))
{
if ((HORIZONTAL_MARGIN - 0x10) > Noise) Noise = HORIZONTAL_MARGIN - 0x10;
break;
}
// No stable horizontal start/end position are found.
if (0xa0 <= Noise) return ERROR_ABORT;
Noise = Noise + 0x10;
Result = Measure_PositionH(Noise);
if (ERROR_SUCCEED != Result) return Result;
};
Data[0] = Noise + 0x10;
return ERROR_SUCCEED;
}
unsigned char Read_Phase_Info(unsigned char Color)
{
RTDSetByte(MARGIN_B_7D, Color);
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
Wait_Finish();
if (ERROR_SUCCEED != Data[0]) return Data[0];
RTDRead(AUTO_PHASE0_88, 4, Y_INC);
Data[4] = Data[3];
Data[5] = Data[2];
Data[6] = Data[1];
Data[7] = Data[0];
return ERROR_SUCCEED;
}
#if (AUTO_PHASE_OPTION == 1)
unsigned char Read_All_Info()
{
unsigned long MaxSum;
if (ERROR_SUCCEED != Read_Phase_Info(COLORS_RED)) return ERROR_INPUT;
MaxSum = ((unsigned long *)Data)[1] >> 1;
if (ERROR_SUCCEED != Read_Phase_Info(COLORS_GREEN)) return ERROR_INPUT;
MaxSum += ((unsigned long *)Data)[1] >> 1;
if (ERROR_SUCCEED != Read_Phase_Info(COLORS_BLUE)) return ERROR_INPUT;
((unsigned long *)Data)[1] = MaxSum + (((unsigned long *)Data)[1] >> 1);
return ERROR_SUCCEED;
}
#endif
unsigned char FindColor(void)
{
unsigned char BestColor, SelColor;
unsigned long MaxSum;
RTDSetByte(DIFF_THRED_7E, 0x30);
MaxSum = 0;
SelColor = COLORS_RED;
do
{
((unsigned long*)Data)[0] = PhaseSearch(SelColor, HWAUTO_STEP_8);
if (0xffffffffL == ((unsigned long*)Data)[0]) return COLORS_FAIL;
if (MaxSum < ((unsigned long *)Data)[0])
{
BestColor = SelColor;
MaxSum = ((unsigned long *)Data)[0];
}
if (COLORS_RED == SelColor)
SelColor = COLORS_GREEN;
else if (COLORS_GREEN == SelColor)
SelColor = COLORS_BLUE;
else
break;
}
while (1);
return (MaxSum ? BestColor : COLORS_NONE);
}
unsigned long PhaseSearch(unsigned char SelColor, unsigned char SelStep)
{
unsigned long idata ulMaxSum;
unsigned char idata count, best;
RTDSetBit(MARGIN_B_7D, 0xfc, SelColor & 0x03);
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
RTDSetByte(HW_AUTO_PHASE_9E, 0x00);
#if (HARDWARE_AUTO)
// Issac : Because H/W auto phase search may cause underflow at start and stop,
// frame-sync watch-dog must be disabled.
Disable_Watch_Dog(WATCH_DOG_FRAMESYNC);
SelStep &= 0x03;
RTDSetByte(HW_AUTO_PHASE_9E, (SelStep & 0x03) | 0x04);
SelStep = (HWAUTO_STEP_8 == SelStep) ? 8 : (HWAUTO_STEP_4 == SelStep) ? 4 : (HWAUTO_STEP_2 == SelStep) ? 2 : 1;
ulMaxSum = 0;
best = 0;
count = 0;
// Issac : Using Wait_For_Event(EVENT_IVS) instead of Wait_For_IVS().
// Because H/W auto phase search may cause underflow at start and stop.
// Wait_For_Event() will not check underflow/overflow.
Wait_For_Event(EVENT_IVS);
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x77);
if (Wait_For_IVS() & (EVENT_UNDERFLOW | EVENT_OVERFLOW)) return 0xffffffff;
do
{
if (Wait_For_IVS() & (EVENT_UNDERFLOW | EVENT_OVERFLOW)) return 0xffffffff;
RTDRead(AUTO_PHASE0_88 + 1, 3, Y_INC);
Data[4] = Data[2];
Data[5] = Data[1];
Data[6] = Data[0];
Data[7] = 0;
if (ulMaxSum < ((unsigned long *)Data)[1])
{
ulMaxSum = ((unsigned long *)Data)[1];
best = count;
}
count += SelStep;
}
while (32 > count);
RTDSetByte(HW_AUTO_PHASE_9E, 0x00); // Switch back to software auto phase
RTDSetByte(AUTO_ADJ_CTRL_7F, 0x00);
Wait_For_Event(EVENT_IVS);
Wait_Finish();
if (ERROR_SUCCEED != Data[0]) return 0xffffffff;;
Enable_Watch_Dog(WATCH_DOG_FRAMESYNC);
Data[0] = best;
#else
SelStep = (HWAUTO_STEP_8 == SelStep) ? 8 : (HWAUTO_STEP_4 == SelStep) ? 4 : (HWAUTO_STEP_2 == SelStep) ? 2 : 1;
ulMaxSum = 0;
best = 0;
count = 0;
do
{
Set_Phase(count << 2);
if (ERROR_SUCCEED != Read_Phase_Info(SelColor)) return 0xffffffff;
if (ulMaxSum < ((unsigned long *)Data)[1])
{
ulMaxSum = ((unsigned long *)Data)[1];
best = count;
}
count += SelStep;
}
while (32 > count);
Data[0] = best;
#endif
return bPowerDownWhenAuto ? 0xffffffff : ulMaxSum;
}
unsigned char Auto_Clock_Do(unsigned char NM, unsigned char Color)
{
unsigned char ucResult;
unsigned char count, delta, stop;
// stMUD.CLOCK must be 4N at first
stMUD.CLOCK = (stMUD.CLOCK) & 0xfc;
Set_Clock();
///////////////////////////////
// Measure (V) Start & End //
///////////////////////////////
ucResult = Measure_PositionV(NM);
if (ERROR_SUCCEED != ucResult) return ucResult;
delta = (800 < usIPH_ACT_WID) ? 100 : 50;
NM = NM + 0x10;
stop = 0;
count = 10;
do
{
///////////////////////////////
// Measure (H) Start & End //
///////////////////////////////
ucResult = Measure_PositionH(NM);
if (ERROR_SUCCEED != ucResult) return ucResult;
usH_End = usH_End + 1 - usH_Start;
// H_Active Delta
if (usH_End < usIPH_ACT_WID)
{
if ((usIPH_ACT_WID - usH_End) >= (2 * delta))
{
stop = 1;
}
else
{
usH_Start = (unsigned long)(usIPH_ACT_WID - usH_End) * (usADC_Clock + (unsigned int)stMUD.CLOCK - 128)
/ (unsigned long)usIPH_ACT_WID;
usH_Start = (usH_Start + 2) & 0xfffc;
if ((usH_Start + stMUD.CLOCK) > (128 + delta))
{
stop = 1;
}
else
{
stMUD.CLOCK += usH_Start;
}
}
}
else
{
if ((usH_End - usIPH_ACT_WID) >= (2 * delta))
{
stop = 1;
}
else
{
usH_Start = (unsigned long)(usH_End - usIPH_ACT_WID) * (usADC_Clock + (unsigned int)stMUD.CLOCK - 128)
/ (unsigned long)usIPH_ACT_WID;
usH_Start = (usH_Start + 2) & 0xfffc;
//if ((stMUD.CLOCK - usH_Start) < (128 - delta))
if (stMUD.CLOCK < (usH_Start + 128 - delta))
{
stop = 1;
}
else
{
stMUD.CLOCK -= usH_Start;
}
}
}
if (stop) break;
Set_Clock();
if (0 == usH_Start) break;
}
while (--count);
if (0 == count || 0 != stop) return ERROR_ABORT;
// Prevent from 1/2-line moire and smear effect.
if ((usH_End >= usIPH_ACT_WID && (128 + 4) == stMUD.CLOCK)
|| (usH_End < usIPH_ACT_WID && (128 - 4) == stMUD.CLOCK))
{
stMUD.CLOCK = 128;
Set_Clock();
ucResult = Measure_PositionH(NM);
if (ERROR_SUCCEED != ucResult) return ucResult;
usH_End = usH_End + 1 - usH_Start;
}
#if (AUTO_CLOCK_STEP < 4)
if (COLORS_NONE == Color)
{
return ERROR_SUCCEED;
}
else
{
unsigned long ulMaxVal;
// Save 4N clock
stop = stMUD.CLOCK;
stMUD.CLOCK += (usIPH_ACT_WID >= usH_End) ? 4 : 2;
Set_Clock();
// Set threshold for Clock Search
RTDSetByte(DIFF_THRED_7E, 0x18);
count = stop;
ulMaxVal = 0;
delta = 6; // Initial value must be (N * AUTO_CLOCK_STEP)
do
{
Data[0] = Measure_PositionH(NM);
if (ERROR_SUCCEED != Data[0]) return ucResult;
usH_End = usH_End + 1 - usH_Start;
if (usH_End > (usIPH_ACT_WID + 2))
{
((unsigned long*)Data)[0] = 0;
}
else
{
((unsigned long*)Data)[0] = PhaseSearch(Color, HWAUTO_STEP_4);
if (0xffffffffL == ((unsigned long*)Data)[0]) return ERROR_INPUT;
}
if (ulMaxVal < ((unsigned long*)Data)[0])
{
ulMaxVal = ((unsigned long*)Data)[0];
count = stMUD.CLOCK;
}
if (0x00 == delta)
{
// Check if default clock is the best when clock searching range is larger than default.
if (128 < stMUD.CLOCK)
{
stMUD.CLOCK = 128;
Set_Clock();
continue;
}
break;
}
delta -= AUTO_CLOCK_STEP;
stMUD.CLOCK -= AUTO_CLOCK_STEP;
Set_Clock();
}
while (1);
stMUD.CLOCK = (ulMaxVal > ((unsigned long)usIPH_ACT_WID << 10)) ? count : stop;
Set_Clock();
}
#endif
return ERROR_SUCCEED;
}
unsigned char Auto_Phase_Do(unsigned char NM, unsigned char Color)
{
unsigned char ucResult;
unsigned long ulMaxSum;
if (COLORS_NONE == Color) return ERROR_ABORT;
Data[0] = Measure_PositionH(NM);
if (ERROR_SUCCEED != Data[0]) return Data[0];
// Set threshold for Phase Search
RTDSetByte(DIFF_THRED_7E, 0x40);
ulMaxSum = PhaseSearch(Color, HWAUTO_STEP_2);
if (0xffffffffL == ulMaxSum) return ERROR_INPUT;
if (0 == ulMaxSum) return ERROR_ABORT;
// PhaseSearch() will reture the best phase into Data[0];
ucResult = Data[0];
#if (AUTO_PHASE_OPTION == 1)
{
unsigned char ucPhase, ucBest;
unsigned long ulTemp0, ulTemp1, ulTemp2;
ucPhase = (ucResult - 3) & 0x1f;
Set_Phase(ucPhase << 2);
if (ERROR_SUCCEED != Read_All_Info()) return ERROR_INPUT;
ulTemp0 = ((unsigned long*)Data)[1];
ucPhase = (ucPhase + 1) & 0x1f;
Set_Phase(ucPhase << 2);
if (ERROR_SUCCEED != Read_All_Info()) return ERROR_INPUT;
ulTemp1 = ((unsigned long*)Data)[1];
ucResult = (ucResult + 3) & 0x1f;
ulMaxSum = 0;
do
{
ucPhase = (ucPhase + 1) & 0x1f;
Set_Phase(ucPhase << 2);
if (ERROR_SUCCEED != Read_All_Info()) return ERROR_INPUT;
ulTemp2 = ((unsigned long*)Data)[1];
((unsigned long*)Data)[0] = ulTemp2 + ulTemp1 + ulTemp0
- ((ulTemp1 > ulTemp0 ? ulTemp1 - ulTemp0 : ulTemp0 - ulTemp1) / 2)
- ((ulTemp1 > ulTemp2 ? ulTemp1 - ulTemp2 : ulTemp2 - ulTemp1) / 2);
if (((unsigned long*)Data)[0] > ulMaxSum)
{
ulMaxSum = ((unsigned long*)Data)[0];
ucBest = (ucPhase - 1) & 0x1f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -