📄 drvauto.c
字号:
#if 1
//may_070406_checkfullscreen
//if(u16PosBff > MAX_PC_AUTO_H_START || u16PosBff < MIN_PC_AUTO_H_START)
if(u16PosBff > MDrv_Mode_GetStdModeResH(pstModesetting->u8ModeIndex)) // check overflow
{
AUTOMSG(printf("H start limit: %u\n", u16PosBff));
u16PosBff = MDrv_Mode_GetStdModeHStart(pstModesetting->u8ModeIndex);
bResult = FALSE;
}
#else
if(u16PosBff > MDrv_Mode_GetStdModeResH(pstModesetting->u8ModeIndex)) // check overflow
{
MDrv_WriteByte( BK_SELECT_00, u8Bank );
return FALSE;
}
#endif
pstModesetting->u16HorizontalStart = u16PosBff;
pstModesetting->u16DefaultHStart = u16PosBff;
MDrv_Write2Byte(BK_SC_IP1F2_05_L, u16PosBff);
AUTOMSG(printf("AutoPosition HStart=0x%x\n", pstModesetting->u16DefaultHStart);)
// vertical positoin
u16PosBff = MDrv_Auto_GetPosition(BK_SC_IP1F2_12_L, u8VSyncTime); // auto vertical start position detected result
if( abs(MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex)-(MDrv_Auto_GetPosition(BK_SC_IP1F2_14_L, u8VSyncTime)-MDrv_Auto_GetPosition(BK_SC_IP1F2_12_L, u8VSyncTime))) >
(MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex)/4) )
{
u16PosBff = MDrv_Mode_GetStdModeVStart(pstModesetting->u8ModeIndex);
}
#if 1
//may_070406_checkfullscreen
if(u16PosBff > MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex)) // check overflow
{
AUTOMSG(printf("V start limit: %u\n", u16PosBff));
u16PosBff = MDrv_Mode_GetStdModeVStart(pstModesetting->u8ModeIndex);
bResult = FALSE;
}
#else
if(u16PosBff > MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex)) // check overflow
{
MDrv_WriteByte( BK_SELECT_00, u8Bank );
return FALSE;
}
#endif
pstModesetting->u16VerticalStart = u16PosBff;
pstModesetting->u16DefaultVStart = u16PosBff;
#if 0
if(MDrv_Mode_GetStdModeResV(pstModesetting->u8ModeIndex) == 350) // if IBM VGA 640x350 then use 640x400 resolution and move to middle of screen
{
u16PosBff -= ((400 - 350) / 2);
}
#endif
MDrv_Write2Byte(BK_SC_IP1F2_04_L, u16PosBff);
MDrv_WriteByte( BK_SELECT_00, u8Bank );
AUTOMSG(printf("AutoPosition VStart=0x%x\n", pstModesetting->u16VerticalStart);)
return bResult;
}
//*************************************************************************
//Function name: MDrv_Auto_GetTransPos
//Passing parameter:
// U8 u8VSyncTime : VSync time
//Return parameter:
// U8: If faile, return -1. else return phase setting
//Description: Get trans-position.
//*************************************************************************
U8 MDrv_Auto_GetTransPos(U8 u8VSyncTime)
{
U16 u16ComparePos; // compare start position
U8 u8AdjustPhase = 0x20,u8PhaseDelta = 0x20; // phase data buffer
U8 u8Bank;
u8Bank = MDrv_ReadByte( BK_SELECT_00 );
MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );
MDrv_ADC_SetADCPhase(0x00); // intialize
u16ComparePos = MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime);
while(1)
{
MDrv_ADC_SetADCPhase(u8AdjustPhase); // set phase
u8PhaseDelta /= 2; // next step
if(u8PhaseDelta == 0x00) // check end
break;
if(MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime) == u16ComparePos) // find critical phase
u8AdjustPhase += u8PhaseDelta; // right shift
else
u8AdjustPhase -= u8PhaseDelta; // left shift
if(MDrv_Auto_CheckSyncLoss()) // check no signal
{
MDrv_WriteByte( BK_SELECT_00, u8Bank );
return -1;
}
} // while
MDrv_WriteByte( BK_SELECT_00, u8Bank );
return (u8AdjustPhase);
}
//*************************************************************************
//Function name: MDrv_Auto_GetActualWidth
//Passing parameter:
// U8 u8VSyncTime : VSync time
//Return parameter:
// U16: return actual image width
//Description: Get actual image width.
//*************************************************************************
U16 MDrv_Auto_GetActualWidth(U8 u8VSyncTime)
{
U16 u16HStart; // actual horizontal start
U8 u8Bank;
U16 u16Width;
u8Bank = MDrv_ReadByte( BK_SELECT_00 );
MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );
MDrv_ADC_SetADCPhase(0x00); // initialize phase value
u16HStart = MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime); // horizontal start position
MDrv_Auto_GetTransPos(u8VSyncTime); // seek critical phase
u16Width = ((MDrv_Auto_GetPosition(BK_SC_IP1F2_15_L, u8VSyncTime) - u16HStart) + 1); // actual image width
MDrv_WriteByte( BK_SELECT_00, u8Bank );
return u16Width;
}
//*************************************************************************
//Function name: MDrv_Auto_TuneHTotal
//Passing parameter:
// U8 u8VSyncTime: VSync time
// MS_PCADC_MODESETTING_TYPE *pstModesetting: Current PC mode setting
//Return parameter:
// BOOLEAN: Success status. (If faile, return FALSE.)
//Description: auto-tune horizontal total.
//*************************************************************************
BOOLEAN MDrv_Auto_TuneHTotal(U8 u8VSyncTime, MS_PCADC_MODESETTING_TYPE *pstModesetting)
{
U16 u16ActualWidth; // actual width
U16 u16StdWidth; // standard width
U16 u16HTotalBff; // horizontal total buffer
BOOLEAN bResult = FALSE;
MDrv_ADC_SetADCPhase(0x00); // initialize phase value
u16ActualWidth = MDrv_Auto_GetPosition(BK_SC_IP1F2_15_L, u8VSyncTime) - MDrv_Auto_GetPosition(BK_SC_IP1F2_13_L, u8VSyncTime);
AUTOHTMSG(printf("\r\n"));
AUTOHTMSG(printf("\r\nTuneHTotal"));
AUTOHTMSG(printf("\r\nModeIdx=%bu", pstModesetting->u8ModeIndex));
// get standard display width
u16StdWidth = MDrv_Mode_GetStdModeResH(pstModesetting->u8ModeIndex);
AUTOHTMSG(printf("\r\nActualWidth=%x", u16ActualWidth));
AUTOHTMSG(printf("\r\nStdWidth=%x", u16StdWidth));
AUTOHTMSG(printf("\r\n"));
// kevin 071025_0 test if(abs(u16ActualWidth - u16StdWidth) > (u16StdWidth / 6)) // check actual width over standard
if(abs(u16ActualWidth - u16StdWidth) > (u16StdWidth / 3)) // check actual width over standard
{
AUTOHTMSG(printf("\r\nAct Width Over"));
return FALSE;
}
//u16HTotalBff = pstModesetting->u16HorizontalTotal; // intialize horizontal total buffer
//AUTOHTMSG(printf("\r\nInit HT=0x%x", u16HTotalBff));
u16HTotalBff = MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex);
AUTOHTMSG(printf("\r\nTbl HT=0x%x", u16HTotalBff));
if(abs(u16ActualWidth - u16StdWidth) > 1) // check width difference
{
// calculate horizontal total
u16HTotalBff = ((U32) pstModesetting->u16HorizontalTotal * u16StdWidth) / u16ActualWidth;
AUTOHTMSG(printf("\r\nCal HT=0x%x", u16HTotalBff));
// check over range of adjusting
if(abs(u16HTotalBff - MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex)) > ADJUST_CLOCK_RANGE)
{
AUTOHTMSG(printf("\r\nAct HT Over"));
return FALSE;
}
MDrv_ADC_SetADCClk(u16HTotalBff); // set clock
}
// check width
AUTOHTMSG(printf("\r\nCheck Width"));
u16ActualWidth = MDrv_Auto_GetActualWidth(u8VSyncTime);
AUTOHTMSG(printf("\r\nActualWidth=%x", u16ActualWidth));
if(u16ActualWidth != u16StdWidth) // match width
{
AUTOHTMSG(printf("\r\n Width --> Not Match"));
// adjust horizontal total
u16HTotalBff = u16HTotalBff + (u16StdWidth - u16ActualWidth);
MDrv_ADC_SetADCClk(u16HTotalBff);
u16ActualWidth = MDrv_Auto_GetActualWidth(u8VSyncTime);
AUTOHTMSG(printf(", ActualWidth=%x", u16ActualWidth));
// adjust horizontal total again
u16HTotalBff = u16HTotalBff + (u16StdWidth - u16ActualWidth);
}
//AUTOHTMSG(printf("--> 1st Match"));
if(u16HTotalBff & 0x01) // match width and check odd
{
MDrv_ADC_SetADCClk(u16HTotalBff - 1); // find decrement
u16ActualWidth = MDrv_Auto_GetActualWidth(u8VSyncTime);
if(u16ActualWidth == u16StdWidth) // match width
{
AUTOHTMSG(printf("--> 2nd Match"));
u16HTotalBff--;
}
else
{
AUTOHTMSG(printf("--> 2nd Not Match"));
MDrv_ADC_SetADCClk(u16HTotalBff + 1); // find increment
u16ActualWidth = MDrv_Auto_GetActualWidth(u8VSyncTime);
AUTOHTMSG(printf("\r\nActualWidth=%x", u16ActualWidth));
if(u16ActualWidth == u16StdWidth) // match width
{
AUTOHTMSG(printf("--> 3rd Match"));
u16HTotalBff++;
}
}
}
if (u16HTotalBff & 0x01)// kevin 071102_0 only for demo
u16HTotalBff++;
AUTOHTMSG(printf("\r\n Temp Htol=0x%x", u16HTotalBff));
AUTOHTMSG(printf("\r\n Get Htol=0x%x",MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex)));
AUTOHTMSG(printf("\r\n CLK Range=0x%x", ADJUST_CLOCK_RANGE));
AUTOHTMSG(printf("\r\n CLK Range=0x%x", (g_PcadcModeSetting.u16HorizontalTotal/4)));
// check horizontal total range
AUTOHTMSG(printf("\r\n Chk Hor. Range --> "));
if(abs(u16HTotalBff - (MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex))) <= ADJUST_CLOCK_RANGE)
{
AUTOHTMSG(printf("OK"));
pstModesetting->u16HorizontalTotal = u16HTotalBff;
pstModesetting->u16DefaultHTotal = u16HTotalBff;
bResult = TRUE;
}
else
{
AUTOHTMSG(printf("NG =0x%x", abs(u16HTotalBff - (MDrv_Mode_GetStdModeHTotal(pstModesetting->u8ModeIndex)))));
}
MDrv_ADC_SetADCClk(pstModesetting->u16HorizontalTotal); // setting ADC clock
MDrv_ADC_SetADCPhase(pstModesetting->u8Phase); // setting ADC phase
AUTOHTMSG(printf("AutoHtt 0x%x\n", pstModesetting->u16HorizontalTotal);)
return bResult;
}
//*************************************************************************
//Function name: MDrv_Auto_GetPhaseVal
//Passing parameter: NO
//Return parameter:
// U32: Return full image sun of difference value between two pixles
//Description: Get auto phase value.
//*************************************************************************
U32 MDrv_Auto_GetPhaseVal(void)
{
DWordType dwPhaseValBff; // double word buffer
U8 u8Bank;
u8Bank = MDrv_ReadByte( BK_SELECT_00 );
MDrv_WriteByte( BK_SELECT_00, REG_BANK_IP1F2 );
MDrv_Auto_WaitStatusReady(BK_SC_IP1F2_19_L, _BIT1);
dwPhaseValBff.separate._byte0 = MDrv_ReadByte(BK_SC_IP1F2_1A_L);
dwPhaseValBff.separate._byte1 = MDrv_ReadByte(BK_SC_IP1F2_1A_H);
dwPhaseValBff.separate._byte2 = MDrv_ReadByte(BK_SC_IP1F2_1B_L);
dwPhaseValBff.separate._byte3 = MDrv_ReadByte(BK_SC_IP1F2_1B_H);
MDrv_WriteByte( BK_SELECT_00, u8Bank );
return dwPhaseValBff.u32Total;
}
//*************************************************************************
//Function name: MDrv_Auto_TunePhase
//Passing parameter:
// U8 u8VSyncTime: VSync time
// MS_PCADC_MODESETTING_TYPE *pstModesetting: Current PC mode setting
//Return parameter:
// BOOLEAN: Success status. (If faile, return FALSE.)
//Description: auto-tune phase.
//*************************************************************************
#define AUTO_PHASE_STEP 4
BOOLEAN MDrv_Auto_TunePhase(U8 u8VSyncTime, MS_PCADC_MODESETTING_TYPE *pstModesetting)
{
U8 u8Index; // loop index
U32 u32AutoPhaseVal; // auto phase value result
#if AUTO_PHASE_METHOD
{
U32 u32MiniPhaseVal = -1; // minimum phase value
U8 u8WorstPhase1,u8WorstPhase2;
u8WorstPhase1 = 0x00; // initizlize
for(u8Index = u8WorstPhase1; u8Index <= 0x3f; u8Index += AUTO_PHASE_STEP)
{
MDrv_ADC_SetADCPhase(u8Index);
MDrv_Timer_Delayms(u8VSyncTime); // delay 1 frame
u32AutoPhaseVal = MDrv_Auto_GetPhaseVal();
if(u32AutoPhaseVal < u32MiniPhaseVal) // check minimum
{
u8WorstPhase1 = u8Index; // refresh best phase
u32MiniPhaseVal = u32AutoPhaseVal; // refresh minimum value
}
if(MDrv_Auto_CheckSyncLoss()) // check no signal
return FALSE;
} // for
// initizlize
u8WorstPhase2 = (u8WorstPhase1 - AUTO_PHASE_STEP + 1) & 0x3f;
u8WorstPhase1 = (u8WorstPhase1 + AUTO_PHASE_STEP) & 0x3f;
u32MiniPhaseVal = -1;
for(u8Index = u8WorstPhase2; u8Index != u8WorstPhase1; u8Index = ((u8Index + 1) & 0x3f))
{
MDrv_ADC_SetADCPhase(u8Index);
MDrv_Timer_Delayms(u8VSyncTime); // delay 1 frame
u32AutoPhaseVal = MDrv_Auto_GetPhaseVal();
if(u32AutoPhaseVal < u32MiniPhaseVal) // check minimum
{
u8WorstPhase2 = u8Index; // refresh best phase
u32MiniPhaseVal = u32AutoPhaseVal; // refresh minimum value
}
if(MDrv_Auto_CheckSyncLoss()) // check no signal
return FALSE;
} // for
pstModesetting->u8Phase = (u8WorstPhase2 + (0x3f / 2)) & 0x3f;
}
#else
{
U32 u32MaxPhaseVal = 0; // maximum phase value
U8 u8BestPhase1,u8BestPhase2;
u8BestPhase1 = 0x00; // initizlize
for(u8Index = u8BestPhase1; u8Index <= 0x3f; u8Index += AUTO_PHASE_STEP)
{
MDrv_ADC_SetADCPhase(u8Index);
MDrv_Timer_Delayms(u8VSyncTime); // delay 1 frame
u32AutoPhaseVal = MDrv_Auto_GetPhaseVal();
if(u32AutoPhaseVal > u32MaxPhaseVal) // check maximum
{
u8BestPhase1 = u8Index; // refresh best phase
u32MaxPhaseVal = u32AutoPhaseVal; // refresh maximum value
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -