📄 autofunc.c
字号:
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 4
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;
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoTuneOffset
//
// <Description>: auto-tune R/G/B Offset.
//
// <Returns> : Success status.
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// ucVSyncTime - In - VSync time
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoTuneOffset(BYTE ucVSyncTime)
{
BYTE ucRedOffset = 0x80, ucGreenOffset = 0x80, ucBlueOffset = 0x80;
BYTE ucOffsetDelta = 0x80; // adjust step
BYTE ucATGStatus; // auto gain status
BYTE ucFlowFlag = 0x00; // underflow or overflow flag
BYTE ucBank;
ucBank = msReadByte( BK0_00_REGBK);
#ifdef AUTO_DEBUG_EN
putstr("\r\nAuto Offset:");
#endif
while(1)
{
ucOffsetDelta /= 2; // next
if (ucOffsetDelta == 0x00) // check end
break;
msAdjustAdcOffset(ucRedOffset, ucGreenOffset, ucBlueOffset); // program R/G/B offset
Delay1ms_WatchDog(ucVSyncTime * 3); // wait stable
msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );
msAutoWaitStatusReady(BK0_C8_ATGCTRL, _BIT1);
ucATGStatus = msReadByte(BK0_C9_ATGST); // get auto gain status
// red
if (_bit2_(ucATGStatus))
{
ucRedOffset += ucOffsetDelta;
ucFlowFlag |= _BIT0;
}
else
{
ucRedOffset -= ucOffsetDelta;
ucFlowFlag |= _BIT1;
}
// green
if (_bit1_(ucATGStatus))
{
ucGreenOffset += ucOffsetDelta;
ucFlowFlag |= _BIT2;
}
else
{
ucGreenOffset -= ucOffsetDelta;
ucFlowFlag |= _BIT3;
}
// blue
if (_bit0_(ucATGStatus))
{
ucBlueOffset += ucOffsetDelta;
ucFlowFlag |= _BIT4;
}
else
{
ucBlueOffset -= ucOffsetDelta;
ucFlowFlag |= _BIT5;
}
} // while
// adjust offset after auto-tune
g_PcSetting.AdcRedOffset= ucRedOffset;
g_PcSetting.AdcGreenOffset= ucGreenOffset;
g_PcSetting.AdcBlueOffset= ucBlueOffset;
msAdjustAdcOffset(g_PcSetting.AdcRedOffset, g_PcSetting.AdcGreenOffset, g_PcSetting.AdcBlueOffset);
msWriteByte( BK0_00_REGBK, ucBank );
if (ucFlowFlag == 0x3f)
return TRUE;
else
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// <Function>: msAutoTuneGain
//
// <Description>: auto-tune R/G/B gain.
//
// <Returns> : Success status.
//
// <Parameter>: - <Flow> - <Description>
//-----------------------------------------------------------------------------
// ucVSyncTime - In - VSync time
///////////////////////////////////////////////////////////////////////////////
BOOL msAutoTuneGain(BYTE ucVSyncTime)
{
BYTE ucRedGain = 0x80, ucGreenGain = 0x80, ucBlueGain = 0x80;
BYTE ucGainDelta = 0x80; // adjust step
BYTE ucATGStatus; // auto gain status
BYTE ucFlowFlag = 0x00; // underflow or overflow flag
BYTE ucResultR,ucResultB,ucResultG;
BYTE ucBank;
ucBank = msReadByte( BK0_00_REGBK);
#ifdef AUTO_DEBUG_EN
putstr("\r\nAuto Gain:");
#endif
while(1)
{
ucGainDelta /= 2; // next
if (ucGainDelta == 0x00) // check end
break;
msAdjustAdcGain(ucRedGain, ucGreenGain, ucBlueGain); // program R/G/B gain
Delay1ms_WatchDog(ucVSyncTime * 3); // wait stable
msWriteByte( BK0_00_REGBK, REG_BANK_SCALER );
msAutoWaitStatusReady(BK0_C8_ATGCTRL, _BIT1);
ucATGStatus = msReadByte(BK0_C8_ATGCTRL); // get auto gain status
#ifdef AUTO_PATCH_01
msWriteByte(BK0_CA_ATFCHSEL, 0x03);
ucResultR = msReadByte(BK0_CD_ATGVALUE);
msWriteByte(BK0_CA_ATFCHSEL, 0x04);
ucResultG = msReadByte(BK0_CD_ATGVALUE);
msWriteByte(BK0_CA_ATFCHSEL, 0x05);
ucResultB = msReadByte(BK0_CD_ATGVALUE);
if( ucResultR == 0xFF )
ucATGStatus |= _BIT7;
else
ucATGStatus &= ~_BIT7;
if( ucResultB == 0xFF )
ucATGStatus |= _BIT5;
else
ucATGStatus &= ~_BIT5;
if( ucResultG== 0xFF )
ucATGStatus |= _BIT6;
else
ucATGStatus &= ~_BIT6;
#endif
// red
if (_bit7_(ucATGStatus))
{
ucRedGain -= ucGainDelta;
ucFlowFlag |= _BIT0;
}
else
{
ucRedGain += ucGainDelta;
ucFlowFlag |= _BIT1;
}
// green
if (_bit6_(ucATGStatus))
{
ucGreenGain -= ucGainDelta;
ucFlowFlag |= _BIT2;
}
else
{
ucGreenGain += ucGainDelta;
ucFlowFlag |= _BIT3;
}
// blue
if (_bit5_(ucATGStatus))
{
ucBlueGain -= ucGainDelta;
ucFlowFlag |= _BIT4;
}
else
{
ucBlueGain += ucGainDelta;
ucFlowFlag |= _BIT5;
}
} // while
// adjust gain after auto-tune
g_PcSetting.AdcRedGain= ucRedGain;
g_PcSetting.AdcGreenGain= ucGreenGain;
g_PcSetting.AdcBlueGain= ucBlueGain;
msAdjustAdcGain(g_PcSetting.AdcRedGain, g_PcSetting.AdcGreenGain, g_PcSetting.AdcBlueGain);
msWriteByte( BK0_00_REGBK, ucBank );
if (ucFlowFlag == 0x3f)
return TRUE;
else
return FALSE;
}
/*
BOOL msAutoColorYUV(BYTE ucVSyncTime)
{
BYTE ucBank; // bank buffer
BYTE ucRedGain, ucGreenGain, ucBlueGain, ucTmp, ucATGStatus, ucFlowFlag=0;
ucBank = msReadByte(BK0_00_REGBK); // store bank
msAdjustAdcOffset(0x7C, 0x7F, 0x7C); // Should be in default value
msAdjustAdcGain(0x80, 0x80, 0x80);
Delay1ms_WatchDog(ucVSyncTime*3);
msWriteByte(BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU);
msWriteByte(BK1_18_CALEN, 0x1C); // CALEN
Delay1ms_WatchDog(ucVSyncTime*3);
ucRedGain = 130; // Should be SMPTE 75% color pattern
ucGreenGain = 30;
ucBlueGain = 130; // Should be SMPTE 75% color pattern
msWriteByte(BK0_00_REGBK, REG_BANK_SCALER);
for (ucTmp=0; ucTmp<0xFF; ucTmp++)
{
msAdjustAdcGain(ucRedGain, ucGreenGain, ucBlueGain);
Delay1ms_WatchDog(ucVSyncTime*3);
msAutoWaitStatusReady(BK0_C8_ATGCTRL, _BIT1);
ucATGStatus = msReadByte(BK0_C8_ATGCTRL); // get auto gain status
// Red - Pr
if ( !(ucFlowFlag&_BIT0) )
{
if (_bit7_(ucATGStatus))
{
g_PcSetting.AdcRedGain= ucRedGain; // Save your ADC value
ucFlowFlag |= _BIT0;
}
else
{
ucRedGain++;
ucFlowFlag |= _BIT1;
}
}
// Green - Y
if ( !(ucFlowFlag&_BIT2) )
{
if (_bit6_(ucATGStatus))
{
g_PcSetting.AdcGreenGain= ucGreenGain; // Save your ADC value
ucFlowFlag |= _BIT2;
}
else
{
ucGreenGain++;
ucFlowFlag |= _BIT3;
}
}
// Blue - Pb
if ( !(ucFlowFlag&_BIT4) )
{
if (_bit5_(ucATGStatus))
{
g_PcSetting.AdcBlueGain = ucBlueGain; // Save your ADC value
ucFlowFlag |= _BIT4;
}
else
{
ucBlueGain++;
ucFlowFlag |= _BIT5;
}
}
if ( ucFlowFlag==0x3F )
break;
}
msWriteByte(BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU);
msWriteByte(BK1_18_CALEN, 0xFC); // CALEN
msWriteByte(BK0_00_REGBK, ucBank);
if (ucFlowFlag == 0x3f)
return TRUE;
else
return FALSE;
}
*/
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -