📄 detect.c
字号:
g_wVerticalTotal = msGetVerticalTotal();
if (abs(g_wHorizontalPeriod-SrcHPeriod)>HPeriod_Torlance) // HPeriod changed
return FALSE;
if (abs(g_wVerticalTotal-SrcVTotal)>VTotal_Torlance) // vtotal changed
return FALSE;
SrcHPeriod=g_wHorizontalPeriod;
SrcVTotal=g_wVerticalTotal;
hFreq=HFreq(g_wHorizontalPeriod);//((DWORD)MST_CLOCK_MHZ*10+SrcHPeriod/2)/SrcHPeriod; // round 5
vFreq=VFreq(hFreq, g_wVerticalTotal);//((DWORD)hFreq*1000+(SrcVTotal/2))/SrcVTotal;
//======== for interlace mode========
#if !SOG_ENABLE //for Skypine V sync not stable
if (msReadByte(BK0_EF_STATUS2)&INTM_B)
#endif
{
SrcFlags|=bInterlaceMode;
vFreq*=2;
}
//====================================
printf("\r\nHFreq = %d", hFreq);
printf("\r\nVFreq = %d", vFreq);
// check if input timing is out of range
if (hFreq>MaxInputHFreq || hFreq<MinInputHFreq || vFreq>MaxInputVFreq || vFreq<MinInputVFreq)
{
SrcFlags|=bUnsupportMode;
return TRUE;
}
// search input mode index
{
BYTE modeIndex=0;
InputModeType *modePtr=tStandardMode;
BOOL found=FALSE;
while (modePtr->HFreq)
{
{ if (abs(hFreq-modePtr->HFreq)<modePtr->HSyncTolerence && abs(vFreq-modePtr->VFreq)<modePtr->VSyncTolerence &&
GetSyncPolarity(SrcFlags)&modePtr->Flags)
{ found=TRUE;
g_ucSrcModeIndex=modeIndex;
break;
}
}
modePtr++;
modeIndex++;
}
if (!found) // out of standard input range
{
printMsg("cannot find mode in standard mode");
#define delta hFreq
#define minDelta vFreq
modeIndex=0;
modePtr=tStandardMode;
minDelta=VTotal_Delta;
while (modePtr->HFreq)
{
if (SrcVTotal>tStandardModeResolution[modePtr->ResIndex].DispHeight)
{
delta=abs(SrcVTotal-(modePtr->VTotal));
if (delta<VTotal_Delta && (SrcFlags&bInterlaceMode)==(modePtr->Flags&bInterlaceMode))
{
if (delta<minDelta)
{
minDelta=delta;
g_ucSrcModeIndex=modeIndex;
}
found=TRUE;
}
}
modePtr++;
modeIndex++;
}
#undef delta
#undef minDelta
} // out of standard input range
if (!found)
SrcFlags|=bUnsupportMode;
} // search mode index
return TRUE;
}
BYTE msGetInputStatus(void)
{
BYTE fStatus=0;
WORD inputValue,StatusTemp;
BYTE status;
inputValue=msReadWord(BK0_EB_HSPRD_H)&0x1FFF;
if (inputValue==0x1FFF || inputValue<10)
fStatus|=bHSyncLoss;
inputValue=msReadWord(BK0_ED_VTOTAL_H)&0x7FF;
if (inputValue==0x7FF || inputValue<10)
fStatus|=bVSyncLoss;
status=msReadByte(BK0_EF_STATUS2);
#if 1//Use_CF_MODE0
msWriteByte(BK0_00_REGBK, REG_BANK3_COMB); //Switch bank3 VCF
msWriteByte(BK3_70_COMB_STSA, 0xFF); // clear CF status
msWriteByte(BK0_00_REGBK, REG_BANK_SCALER); //Switch bank0 Scaler
#endif //Use_CF_MODE0
StatusTemp=msReadByte(BK0_EF_STATUS2);
Delay1ms(30); //Delay 30ms
if((status&(bHSyncNegative|bVSyncNegative)) != (StatusTemp&(bHSyncNegative|bVSyncNegative)))
status |= SyncLoss;
fStatus|=(status&0x03); // Get input timing polarity
if (SyncLossState() && !(fStatus&SyncLoss)) // input timing is valid while current state is no sync
{
if (status&INTM_B)
{
msWriteByte(BK0_E2_SWRST0, OP2R_B);
Delay1ms(1);
msWriteByte(BK0_E2_SWRST0, 0);
}
Delay1ms(20);
if (g_bInputTimingChangeFlag)
return fStatus;
status=status&msReadByte(BK0_EF_STATUS2);
if ((status&3)!=(fStatus&3)) // polarity is stable
fStatus|=SyncLoss;
else if (status&0x30) // SOG or CSync input
{
Delay1ms(20);
if (g_bInputTimingChangeFlag)
return fStatus;
status=msReadByte(BK0_EF_STATUS2);
// Check if SOG/CSYNC is valid
if (abs(msReadWord(BK0_ED_VTOTAL_H)-inputValue)>2)
fStatus|=SyncLoss;
if ((status&0x50)==0x50 || (status&0xA0)==0xA0)
fStatus|=SyncLoss;
else if ((status&0x18)==0x18)
fStatus|=SyncLoss; // Check if SOG/CSYNC is valid
}
}
return fStatus;
}
void msProgAnalogWin()
{
_WindowType* pAnalogWindow = &g_WindowInfo;
{
pAnalogWindow->H_CapSize = GetStdModeResH(g_ucSrcModeIndex); // standard display width
pAnalogWindow->V_CapSize = GetStdModeResV(g_ucSrcModeIndex); // standard display height
if (pAnalogWindow->V_CapSize == 350) // if IBM VGA 640x350 then use 640x400 resolution and move to middle of screen
{
pAnalogWindow->V_CapSize = 400;
g_ModeSetting.VStart-= ((400-350)/2);
}
//pAnalogWindow->H_CapStart = g_ModeSetting.DefaultHStart*2 - g_ModeSetting.HStart;
pAnalogWindow->V_CapStart = g_ModeSetting.VStart;
}
SetDisplayWindow();
SetCaptureWindow();
SetScalingRatio( g_InOutCtl.bInterlace );
//msSetScaler();
}
//*******************************************************************
// Function Name: msSetupMode
//
// Decscription: setup registers for input timing,
// return : TRUE,
// caller:
// callee: msModeHandler() in detect.c
//*******************************************************************
BOOL msSetupMode(void)
{
if(SrcFlags&bInterlaceMode)
g_InOutCtl.bInterlace = 1;
else
g_InOutCtl.bInterlace = 0;
Clr_FreeRunModeFlag();
msSetupADC(); // setup ADC block, including polarity & htotal, phase, vco
msCommSetupMode();
SetOutputTimingAndWindow( OUTPUT_SIG);
/*
if (msSetCaptureWindow()==FALSE) // setup capture window
return FALSE;
msSetScalingFactor(); // setup scaling factor
if (msSetOutputDclk()==FALSE) // set output dclk
return TRUE;
*/
msWriteByte(BK0_02_ISELECT, msReadByte(BK0_02_ISELECT)&(~NIS_B));// enable lock input mode
if (g_bInputTimingChangeFlag || msValidTimingDetect()) // check if input timing has changed
return FALSE;
// enable double buffer
msWriteByte(BK0_01_DBFC, 0x04); // enable double bufer.
msWriteByte(BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU);
//msWriteByte(BK1_01_DBFC, 0x01); // enable ADC's double bufer.
msWriteByte(BK0_00_REGBK, REG_BANK_SCALER);
//msSetInterrupt(INTERRUPT_PC);
return TRUE;
}
//*******************************************************************
// Function Name: msSetupADC
//
// Decscription: setup ADC bandwidth/filter, clock, phase for sampling input data
// and R/G/B gains, offsets
// caller: mSar_WriteByte(), msReadByte() in ms_rwreg.c
///
// callee: msSetupMode() in mstar.c
//*******************************************************************
BYTE code ADCWB[5][3]= // ADC parameter table for setup ADC
{ //ADC BandWidth 0D 0F
{0x55, 0x86, 0x05}, // < 15 (MHz)
{0x44, 0x86, 0x02}, // 15 < < 38 (MHz)
{0x33, 0x85, 0x03}, // 38 < < 70 (MHz)
{0x11, 0x83, 0x03}, // 70 < < 155 (MHz)
{0x00, 0x81, 0x03}, // 155 < (MHz)
};
void msSetupADC(void)
{
BYTE ucBank;
WORD tempValue;
ucBank = msReadByte( BK0_00_REGBK);
msWriteByte( BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU );
{// HSync Polarity:
// Leading Edge: Hstart=Hwidth+Hbp, BK1_0C[5]=0, BK0_04[4]=0
// Trailing Edge: Hstart=Hbp, BK1_0C[5]=1, BK0_04[4]=1
if (SrcFlags&bHSyncNegative)
msWriteByte(BK1_0C_GCTRL, msReadByte(BK1_0C_GCTRL)|_BIT7);
else
msWriteByte(BK1_0C_GCTRL, msReadByte(BK1_0C_GCTRL)&(~_BIT7));
}
tempValue=((DWORD)MST_CLOCK_KHZ*10+SrcHPeriod/2)/SrcHPeriod; //calculate hfreq: round 5
tempValue=((DWORD)tempValue*g_ModeSetting.HTotal+5000)/10000; //dclk= hfreq * htotal
// printData("input dclk %d", tempValue);
if (tempValue<15)
tempValue=0;
else if (tempValue<38)//82)
tempValue=1;
else if (tempValue<70)
tempValue=2;
else if (tempValue<155)
tempValue=3;
else
tempValue=4;
msWriteByteMask(BK1_2C, ADCWB[tempValue][0], 0x0F);// R bandwidth
msWriteByte(BK1_2D, ADCWB[tempValue][0]); // setup ADC bandwidth
msWriteByte(BK1_0D_BWCOEF, ADCWB[tempValue][1]); // setup ADC
msWriteByte(BK1_0F_DCOEF, ADCWB[tempValue][2]);
// setup clock
tempValue=g_ModeSetting.HTotal-3;
msWriteByte(BK1_02_PLLDIVM, tempValue>>4);
msWriteByte(BK1_03_PLLDIVL, (tempValue&0xF)<<4);
// setup phase
msWriteByte(BK1_10_CLKCTRL1, (g_ModeSetting.Phase+8)%0x40); // b5-0: clock phase adjust(PHASECC + 8)
msWriteByte(BK1_11_CLKCTRL2, g_ModeSetting.Phase); // b5-0: PHASECC(clock phase adjust)
//printf("\r\ng_ModeSetting.HorizontalTotal=%d", g_ModeSetting.HorizontalTotal);
// setup ADC gain
msWriteByte(BK0_00_REGBK, REG_BANK1_ADC_ACE_MCU); // switch to ADC bank
msWriteByte(BK1_04_RGAIN_ADC, 0xFF-g_PcSetting.AdcRedGain);
msWriteByte(BK1_05_GGAIN_ADC, 0xFF-g_PcSetting.AdcGreenGain);
msWriteByte(BK1_06_BGAIN_ADC, 0xFF-g_PcSetting.AdcBlueGain);
// setup ADC offset
msWriteByte(BK1_07_ROFFS_ADC, 0xFF-g_PcSetting.AdcRedOffset);
msWriteByte(BK1_08_GOFFS_ADC, 0xFF-g_PcSetting.AdcGreenOffset);
msWriteByte(BK1_09_BOFFS_ADC, 0xFF-g_PcSetting.AdcBlueOffset);
msWriteByte( BK0_00_REGBK, ucBank );
}
WORD GetStdModeResH( BYTE ucModeIdx )
{
if (tStandardModeResolution[tStandardMode[ucModeIdx].ResIndex].DispWidth < PanelWidth)
return tStandardModeResolution[tStandardMode[ucModeIdx].ResIndex].DispWidth * 2;
else
return tStandardModeResolution[tStandardMode[ucModeIdx].ResIndex].DispWidth;
return 1;
}
WORD GetStdModeResV( BYTE ucModeIdx )
{
return tStandardModeResolution[tStandardMode[ucModeIdx].ResIndex].DispHeight;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -