📄 mst705Ȧ
字号:
g_wHorizontalPeriod = msGetHorizontalPeriod();
g_wVerticalTotal = msGetVerticalTotal();
printf("\r\n g_wHorizontalPeriod = %d", g_wHorizontalPeriod);
printf("\r\n g_wVerticalTotal = %d", g_wVerticalTotal);
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 (msReadByte(BK0_EF_STATUS2)&INTM_B)
{
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)
{
ucFlagBff = modePtr->Flags;
{
if (abs(hFreq-modePtr->HFreq)<modePtr->HSyncTolerence && abs(vFreq-modePtr->VFreq)<modePtr->VSyncTolerence &&
GetSyncPolarity(SrcFlags)&modePtr->Flags
&& ((IsYPbPrInUse()&&modePtr->Flags&bVideoMode)||IsVGAInUse()) //skip VGA mode in YUV source , specially 480p
)
{
found=TRUE;
g_ucSrcModeIndex=modeIndex;
break;
}
}
modePtr++;
modeIndex++;
}
if (!found) // out of standard input range
{
printMsg("Cann't 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 ucBank,status,fStatus=0;
WORD inputValue,StatusTemp;
ucBank = msReadByte( BK0_00_REGBK);
msWriteByte(BK0_00_REGBK, REG_BANK_SCALER);
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)
{
msWriteByte(BK0_00_REGBK, ucBank);
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)
{
msWriteByte(BK0_00_REGBK, ucBank);
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
}
}
*/
msWriteByte(BK0_00_REGBK, ucBank);
return fStatus;
}
void msProgAnalogWin()
{
_WindowType* pAnalogWindow = &g_WindowInfo;
if(IsVGAInUse())
{
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;
}
else
{
pAnalogWindow->H_CapSize = GetStdModeResH(g_ucSrcModeIndex); // standard display width
pAnalogWindow->V_CapSize = GetStdModeResV(g_ucSrcModeIndex); // standard display height
pAnalogWindow->H_CapStart = GetStdModeHStart(g_ucSrcModeIndex);
pAnalogWindow->V_CapStart = GetStdModeVStart(g_ucSrcModeIndex);
}
printf("\r\npAnalogWindow->V_CapSize=%d", pAnalogWindow->V_CapSize);
printf("\r\npAnalogWindow->H_CapSize=%d", pAnalogWindow->H_CapSize);
g_WindowInfo.V_DisSize = PanelHeight;
if( IsSrcHasSignal() )
{
if( IsYPbPrInUse() )
CalculateAspectRatio();
}
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);
msWriteByte(BK0_00_REGBK, REG_BANK_SCALER);
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>: msCalculatePixClk
//
// <Description>: Calculate pixel clock.
//
// <Returns> : Pixel clock (MHz)
///////////////////////////////////////////////////////////////////////////////
BYTE msCalculatePixClk(void)
{
// RGBMODE_PRINTF("\r\ng_wHorizontalPeriod=%d", g_wHorizontalPeriod);
// RGBMODE_PRINTF("\r\nHFreq=%d", msCalculateHFreqX10(g_wHorizontalPeriod));
// RGBMODE_PRINTF("\r\nHorizontalTotal=%d", g_ModeSetting.HorizontalTotal);
// [Pixel clock] = [HSync] * [Horizontal Total]
return (BYTE)(((DWORD)msCalculateHFreqX10(g_wHorizontalPeriod) *
g_ModeSetting.HTotal + (5000)) / 10000);
}
//*******************************************************************
// 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);
msADC_HSYNC_Polarity(SrcFlags&bHSyncNegative);
msADC_iclamp_clk_rate(msCalculatePixClk());
msADC_iclamp_clpdly(msCalculatePixClk());
msADC_iclamp_clpdur(msCalculatePixClk());
msADC_inputLPF(msCalculatePixClk());
msADC_PLL(msCalculatePixClk());
msADC_SOG_FilterBW(msCalculatePixClk());
// setup clock
tempValue=g_ModeSetting.HTotal-3;
msWriteByte(BK0_00_REGBK, REG_BANK6s01_ADCDTOP );
// PLL divider
msWrite2BytesMask_16bitADDR(BK6s01_01h_ADC_DTOP,tempValue,0x1FFF);
// setup phase
msWriteByte(BK0_00_REGBK, REG_BANK6s00_ADCATOP );
g_ModeSetting.Phase=g_ModeSetting.Phase*16;
msWrite2BytesMask_16bitADDR(BK6s00_0Fh_ADC_ATOP,g_ModeSetting.Phase,0x03FF);
//printf("\r\ng_ModeSetting.HorizontalTotal=%d", g_ModeSetting.HorizontalTotal);
if(IsVGAInUse())
{
// setup ADC gain
msWriteByte(BK0_00_REGBK, REG_BANK6s01_ADCDTOP); // switch to ADC bank
msWrite2BytesMask_16bitADDR(BK6s01_45h_ADC_DTOP,g_PcSetting.AdcRedGain,0x3FFF);
msWrite2BytesMask_16bitADDR(BK6s01_48h_ADC_DTOP,g_PcSetting.AdcGreenGain,0x3FFF);
msWrite2BytesMask_16bitADDR(BK6s01_4Bh_ADC_DTOP,g_PcSetting.AdcBlueGain,0x3FFF);
// setup ADC offset , can't be change
msWrite2BytesMask_16bitADDR(BK6s01_46h_ADC_DTOP,0x00,0x1FFF);
msWrite2BytesMask_16bitADDR(BK6s01_49h_ADC_DTOP,0x00,0x1FFF);
msWrite2BytesMask_16bitADDR(BK6s01_4Ch_ADC_DTOP,0x00,0x1FFF);
}
else //YPBPR
{
InitYPbPrSetting();
// setup ADC gain
msWriteByte(BK0_00_REGBK, REG_BANK6s01_ADCDTOP); // switch to ADC bank
msWrite2BytesMask_16bitADDR(BK6s01_45h_ADC_DTOP,g_YPbPrSetting.AdcRedGain,0x3FFF);
msWrite2BytesMask_16bitADDR(BK6s01_48h_ADC_DTOP,g_YPbPrSetting.AdcGreenGain,0x3FFF);
msWrite2BytesMask_16bitADDR(BK6s01_4Bh_ADC_DTOP,g_YPbPrSetting.AdcBlueGain,0x3FFF);
// setup ADC offset , can't be change
msWrite2BytesMask_16bitADDR(BK6s01_46h_ADC_DTOP,0x800,0x1FFF);
msWrite2BytesMask_16bitADDR(BK6s01_49h_ADC_DTOP,0x100,0x1FFF);
msWrite2BytesMask_16bitADDR(BK6s01_4Ch_ADC_DTOP,0x800,0x1FFF);
}
msWriteByte( BK0_00_REGBK, ucBank );
}
WORD GetStdModeResH( BYTE ucModeIdx )
{
return tStandardModeResolution[tStandardMode[ucModeIdx].ResIndex].DispWidth;
}
WORD GetStdModeResV( BYTE ucModeIdx )
{
return tStandardModeResolution[tStandardMode[ucModeIdx].ResIndex].DispHeight;
}
WORD GetStdModeHStart( BYTE ucModeIdx )
{
return tStandardMode[ucModeIdx].HStart;
}
WORD GetStdModeVStart( BYTE ucModeIdx )
{
return tStandardMode[ucModeIdx].VStart;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -