📄 mst705Ȧ
字号:
// <Function>: msAutoGetActualWidth
//
// <Description>: Get actual image width.
//
// <Returns> : Actual width.
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// ucVSyncTime - In - VSync time
///////////////////////////////////////////////////////////////////////////////
WORD msAutoGetActualWidth(BYTE ucVSyncTime)
{
WORD wHStart; // actual horizontal start
msAdjustAdcPhase(0x00); // initialize phase value
wHStart = msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime); // horizontal start position
msAutoGetTransPos(ucVSyncTime); // seek critical phase
return ((msAutoGetPosition(BK0_D4_AOHEND_L, ucVSyncTime) - wHStart) + 1); // actual image width
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoTuneHTotal
//
// <Description>: auto-tune horizontal total.
//
// <Returns> : Success status.
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// ucVSyncTime - In - VSync time
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoTuneHTotal(BYTE ucVSyncTime)
{
WORD wActualWidth; // actual width
WORD wStdWidth; // standard width
WORD wHTotalBff; // horizontal total buffer
BOOL bResult = FALSE;
msAdjustAdcPhase(0x00); // initialize phase value
wActualWidth = msAutoGetPosition(BK0_D4_AOHEND_L, ucVSyncTime) - msAutoGetPosition(BK0_D0_AOHST_L, ucVSyncTime);
// get standard display width
wStdWidth = StandardModeWidth;
if (abs(wActualWidth - wStdWidth) > (wStdWidth / 4)) // check actual width over standard
{
#ifdef AUTO_DEBUG_EN
putstr("\r\nmsAutoTuneHTotal failed-1");
#endif
return FALSE;
}
wHTotalBff = g_ModeSetting.HTotal; // intialize horizontal total buffer
if (abs(wActualWidth - wStdWidth) > 1) // check width difference
{
// calculate horizontal total
wHTotalBff = ((DWORD)g_ModeSetting.HTotal* wStdWidth) / wActualWidth;
// check over range of adjusting
if (abs(wHTotalBff - StandardModeHTotal)> ADJUST_CLOCK_RANGE) //OWEN 110205
{
#ifdef AUTO_DEBUG_EN
putstr("\r\nmsAutoTuneHTotal failed-2");
printf("\r\nwHTotalBff=%d", wHTotalBff);
printf("\r\nwStdWidth=%d", wStdWidth);
printf("\r\nwActualWidth=%d", wActualWidth);
#endif
return FALSE;
}
msAdjustAdcClock(wHTotalBff); // set clock
}
// check width
wActualWidth = msAutoGetActualWidth(ucVSyncTime);
if (wActualWidth != wStdWidth) // match width
{
// adjust horizontal total
wHTotalBff = wHTotalBff + (wStdWidth - wActualWidth);
msAdjustAdcClock(wHTotalBff);
wActualWidth = msAutoGetActualWidth(ucVSyncTime);
// adjust horizontal total again
wHTotalBff = wHTotalBff + (wStdWidth - wActualWidth);
}
if (wHTotalBff & 0x01) // match width and check odd
{
msAdjustAdcClock(wHTotalBff - 1); // find decrement
wActualWidth = msAutoGetActualWidth(ucVSyncTime);
if (wActualWidth == wStdWidth) // match width
wHTotalBff--;
else
{
msAdjustAdcClock(wHTotalBff + 1); // find increment
wActualWidth = msAutoGetActualWidth(ucVSyncTime);
if (wActualWidth == wStdWidth) // match width
wHTotalBff++;
}
}
#ifdef AUTO_DEBUG_EN
printf("\r\nH. Total = %x", wHTotalBff);
printf("(%d)", wHTotalBff);
#endif
// check horizontal total range
if (abs(wHTotalBff - (StandardModeHTotal)) < ADJUST_CLOCK_RANGE)
{
g_ModeSetting.HTotal= wHTotalBff;
bResult = TRUE;
#ifdef AUTO_DEBUG_EN
putstr("\r\nmsAutoTuneHTotal success");
#endif
}
msAdjustAdcClock(g_ModeSetting.HTotal); // setting ADC clock
msAdjustAdcPhase(g_ModeSetting.Phase); // setting ADC phase
return bResult;
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoGetPhaseVal
//
// <Description>: get auto phase value.
//
// <Returns> : auto phase value.
///////////////////////////////////////////////////////////////////////////////
DWORD msAutoGetPhaseVal(void)
{
DWordType dwPhaseValBff; // double word buffer
BYTE ucBank;
ucBank = msReadByte( BK0_00_REGBK);
msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );
msAutoWaitStatusReady(BK0_DB_ATPCTRL, _BIT1);
dwPhaseValBff.separate._byte0 = msReadByte(BK0_DC_ATPV1);
dwPhaseValBff.separate._byte1 = msReadByte(BK0_DD_ATPV2);
dwPhaseValBff.separate._byte2 = msReadByte(BK0_DE_ATPV3);
dwPhaseValBff.separate._byte3 = msReadByte(BK0_DF_ATPV4);
msWriteByte( BK0_00_REGBK, ucBank );
return dwPhaseValBff.total;
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoTunePhase
//
// <Description>: auto-tune phase.
//
// <Returns> : Success status.
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// ucVSyncTime - In - VSync time
///////////////////////////////////////////////////////////////////////////////
#define AUTO_PHASE_STEP 1
BOOL msAutoTunePhase(BYTE ucVSyncTime)
{
BYTE ucIndex; // loop index
DWORD dwAutoPhaseVal; // auto phase value result
#if AUTO_PHASE_METHOD
{
DWORD dwMiniPhaseVal = -1; // minimum phase value
BYTE ucWorstPhase1, ucWorstPhase2;
ucWorstPhase1 = 0x00; // initizlize
for (ucIndex=ucWorstPhase1; ucIndex<=0x3f; ucIndex+=AUTO_PHASE_STEP)
{
msAdjustAdcPhase(ucIndex);
Delay1ms_WatchDog(ucVSyncTime); // delay 1 frame
dwAutoPhaseVal = msAutoGetPhaseVal();
if (dwAutoPhaseVal < dwMiniPhaseVal) // check minimum
{
ucWorstPhase1 = ucIndex; // refresh best phase
dwMiniPhaseVal = dwAutoPhaseVal; // refresh minimum value
}
if (msAutoCheckSyncLoss()) // check no signal
return FALSE;
} // for
// initizlize
ucWorstPhase2= (ucWorstPhase1 - AUTO_PHASE_STEP + 1) & 0x3f;
ucWorstPhase1 = (ucWorstPhase1 + AUTO_PHASE_STEP) & 0x3f;
dwMiniPhaseVal = -1;
for (ucIndex=ucWorstPhase2; ucIndex!=ucWorstPhase1; ucIndex=((ucIndex+1)&0x3f))
{
msAdjustAdcPhase(ucIndex);
Delay1ms_WatchDog(ucVSyncTime); // delay 1 frame
dwAutoPhaseVal = msAutoGetPhaseVal();
if (dwAutoPhaseVal < dwMiniPhaseVal) // check minimum
{
ucWorstPhase2 = ucIndex; // refresh best phase
dwMiniPhaseVal = dwAutoPhaseVal; // refresh minimum value
}
if (msAutoCheckSyncLoss()) // check no signal
return FALSE;
} // for
g_ModeSetting.Phase = (ucWorstPhase2 + (0x3f / 2)) & 0x3f;
}
#else
{
DWORD dwMaxPhaseVal = 0; // maximum phase value
BYTE ucBestPhase1, ucBestPhase2;
ucBestPhase1 = 0x00; // initizlize
for (ucIndex=ucBestPhase1; ucIndex<=0x3f; ucIndex+=AUTO_PHASE_STEP)
{
msAdjustAdcPhase(ucIndex);
Delay1ms_WatchDog(ucVSyncTime); // delay 1 frame
dwAutoPhaseVal = msAutoGetPhaseVal();
if (dwAutoPhaseVal > dwMaxPhaseVal) // check maximum
{
ucBestPhase1 = ucIndex; // refresh best phase
dwMaxPhaseVal = dwAutoPhaseVal; // refresh maximum value
}
if (msAutoCheckSyncLoss()) // check no signal
return FALSE;
} // for
// initizlize
ucBestPhase2= (ucBestPhase1 - AUTO_PHASE_STEP + 1) & 0x3f;
ucBestPhase1 = (ucBestPhase1 + AUTO_PHASE_STEP) & 0x3f;
dwMaxPhaseVal = 0;
for (ucIndex=ucBestPhase2; ucIndex!=ucBestPhase1; ucIndex=((ucIndex+1)&0x3f))
{
msAdjustAdcPhase(ucIndex);
Delay1ms_WatchDog(ucVSyncTime); // delay 1 frame
dwAutoPhaseVal = msAutoGetPhaseVal();
if (dwAutoPhaseVal > dwMaxPhaseVal) // check maximum
{
ucBestPhase2 = ucIndex; // refresh best phase
dwMaxPhaseVal = dwAutoPhaseVal; // refresh maximum value
}
if (msAutoCheckSyncLoss()) // check no signal
return FALSE;
} // for
g_ModeSetting.Phase = ucBestPhase2;
}
#endif
#ifdef AUTO_DEBUG_EN
printf("\r\nAuto Phase = %x", g_ModeSetting.Phase);
#endif
msAdjustAdcPhase(g_ModeSetting.Phase);
return TRUE;
}
#define READ_BACK_TIME 5 // Need to >= 3
BOOL msADCAutoColor(BYTE ucVSyncTime)
{
BYTE XDATA ucBank; // bank buffer
BYTE XDATA ucTmp, ucStatus, ucFlowFlag=0;
BYTE XDATA ucResultR, ucResultG, ucResultB;
WORD XDATA wCVBCnt;
WORD XDATA dat[6],CD_data_sum;
BYTE XDATA adr[6],CD_data_min,CD_data_max,CD_data_temp;
BYTE XDATA RG_init,GG_init,BG_init;
BYTE XDATA R_target_max,G_target_max,B_target_max;
BYTE XDATA Gain_target_delta;
BYTE XDATA i,j,gainstep;
#if ENABLE_FW_ADC_OFFSET
BYTE XDATA R_target_min,G_target_min,B_target_min;
BYTE XDATA Offset_target_delta;
BYTE XDATA RO_init,GO_init,BO_init;
#endif//#if ENABLE_FW_ADC_OFFSET
///// SET Auto gain/offset target value
if( IsVGAInUse())
{
R_target_max=0xfc; // max-min value so max value =1+252=253
G_target_max=0xfc;
B_target_max=0xfc;
dat[0]=0x1340;dat[1]=0x13a0;dat[2]=0x13c0; // gain initial value
dat[3]=0x0000;dat[4]=0x0000;dat[5]=0x0000; // offset initial value
Gain_target_delta=1;
#if ENABLE_FW_ADC_OFFSET
R_target_min=0x01;
G_target_min=0x01;
B_target_min=0x01;
Offset_target_delta=1;
#endif//#if ENABLE_FW_ADC_OFFSET
}
else
{
// Should be SMPTE 100% color pattern
R_target_max=PbPr_AUTO_ACTIVE_RANGE;
G_target_max=Y_AUTO_ACTIVE_RANGE;
B_target_max=PbPr_AUTO_ACTIVE_RANGE;
dat[0]=0x1150;dat[1]=0x16b0;dat[2]=0x1158; // gain initial value
dat[3]=0x0800;dat[4]=0x0100;dat[5]=0x0800; // offset initial value
Gain_target_delta=1;
#if ENABLE_FW_ADC_OFFSET
R_target_min=PbPr_AUTO_MIN_VALUE;
G_target_min=Y_AUTO_MIN_VALUE;
B_target_min=PbPr_AUTO_MIN_VALUE;
Offset_target_delta=0;//1;
#endif//#if ENABLE_FW_ADC_OFFSET
}
ucBank = msReadByte(BK0_00_REGBK); // store bank
RG_init=1;GG_init=1;BG_init=1;
// gain
adr[0] = 0x8a;adr[1] = 0x90;adr[2] = 0x96; // gain address
// offset
adr[3] = 0x8c;adr[4] = 0x92;adr[5] = 0x98; // offset address
//dat[0]=0x1000;dat[1]=0x1000;dat[2]=0x1000; // gain initial value
#if ENABLE_FW_ADC_OFFSET
RO_init=1;GO_init=1;BO_init=1;
// dat[3]=0x0000;dat[4]=0x0000;dat[5]=0x0000; // offset initial value
#endif//#if ENABLE_FW_ADC_OFFSET
if(IsVGAInUse())
{
g_PcSetting.AdcRedGain = dat[0];
g_PcSetting.AdcGreenGain = dat[1];
g_PcSetting.AdcBlueGain = dat[2];
//#if ENABLE_FW_ADC_OFFSET
g_PcSetting.AdcRedOffset = dat[3];
g_PcSetting.AdcGreenOffset = dat[4];
g_PcSetting.AdcBlueOffset = dat[5];
//#endif//#if ENABLE_FW_ADC_OFFSET
}
else //YPBPR
{
g_YPbPrSetting.AdcRedGain = dat[0];
g_YPbPrSetting.AdcGreenGain = dat[1];
g_YPbPrSetting.AdcBlueGain = dat[2];
//#if ENABLE_FW_ADC_OFFSET
g_YPbPrSetting.AdcRedOffset = dat[3];
g_YPbPrSetting.AdcGreenOffset = dat[4];
g_YPbPrSetting.AdcBlueOffset = dat[5];
//#endif//#if ENABLE_FW_ADC_OFFSET
}
ucStatus = 0;
for (ucTmp=0; ucTmp<50; ucTmp++)
{
if(ucTmp<8 ) gainstep = 16;
else if ( ucTmp < 20 ) gainstep = 8;
else if( ucTmp < 30 ) gainstep = 4;
else if( ucTmp < 50 ) gainstep = 2;
else gainstep = 1;
printf("\r\n %d =", ucTmp );
///// Write Gain/offset vaule to register
msWriteByte( BK0_00_REGBK, REG_BANK6s01_ADCDTOP );
for(i=0;i<6;i++)
msWriteWord(adr[i]+1, dat[i]);
msWriteByte(BK0_00_REGBK, REG_BANK_SCALER);
Delay1ms_WatchDog(ucVSyncTime);
// Delay1ms_WatchDog(ucVSyncTime);
// Delay1ms_WatchDog(ucVSyncTime);
//////////////////////////////////////////////////////////////////////////////////
// Tune Offset
//////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -