📄 pdptimings.cpp
字号:
WORD wYRes : YResolution
WORD wRefreshRate : RefreshRate
PPDP_TIMINGS psTiming : Pointer to output structure
PPDP_TIMINGS asTimings : Array of timings to search
int nSize : Size of array
RETURNS : PDP_ERROR_OK on success
*****************************************************************************/
PDP_ERROR FindTiming(WORD wXRes,WORD wYRes,WORD wRefreshRate,PPDP_TIMINGS psTiming,PPDP_TIMINGS asTimings,int nSize)
{
int nIndex;
for(nIndex=0;nIndex<nSize;nIndex++)
{
if((asTimings[nIndex].wXRes==wXRes) && (asTimings[nIndex].wYRes==wYRes) && (asTimings[nIndex].wRefreshHz==wRefreshRate))
{
// we have found the requested mode!
*psTiming=asTimings[nIndex];
return PDP_ERROR_OK;
}
}
return PDP_ERROR_INVALID_PARAMS;
}
/* This function is translation of the Vesa CVT Spreadsheet Version 1 draft 5 */
PDP_ERROR GetCVT(WORD wXRes,WORD wYRes,WORD wRefreshRate,BOOL bIsReduced,PPDP_TIMINGS psTiming)
{
int VBILines;
int RBMinVBI;
int ActVBILines;
int VFieldRateRqd;
int HPixelsRnd;
int TotalActivePixels;
int VLinesRnd;
int VTotal;
int VSyncBP;
int VBackPorch;
int HBlank;
int TotalPixels;
int HSyncRnd;
int HBackPorch;
int HFrontPorch;
double ActPixelFreq;
double ActHFreq;
double HPeriodEst;
double ActFieldRate;
double IdealDutyCycle;
int CellGranRnd=8;
int LeftMargin=0;
int RightMargin=0;
int TopMargin=0;
int BottomMargin=0;
int VSync=3;
int MinVSyncBP=550;
int MinVPorchRnd=3;
int MinVBPorch=6;
int CPrime=30;
int MPrime=300;
int HSyncPer=8;
int RBMinVBlank=460;
int RBVFPorch=2;
int RBHSyncRnd=32;
int RBHBlank=160;
double ClockStep=0.25;
// Common Parameters
VFieldRateRqd=wRefreshRate;
HPixelsRnd=((int)((float)wXRes/CellGranRnd))*CellGranRnd;
TotalActivePixels=HPixelsRnd+LeftMargin+RightMargin;
VLinesRnd=wYRes;
// figure out the aspect ratio (and thus the vsync period)
if((int)(wYRes*4/3)==wXRes)
{// 4:3
VSync=4;
}
if((int)(wYRes*16/9)==wXRes)
{// 16:9
VSync=5;
}
if((int)(wYRes*16/10)==wXRes)
{// 16:10
VSync=6;
}
if((int)(wYRes*5/4)==wXRes)
{// 5:4
VSync=7;
}
if((int)(wYRes*15/9)==wXRes)
{// 15:9
VSync=7;
}
if(!bIsReduced) // Standard CRT Timings
{
HPeriodEst=((1.0/VFieldRateRqd)-MinVSyncBP/1000000.0)/(VLinesRnd+(2.0*TopMargin)+MinVPorchRnd)*1000000.0;
VSyncBP=((int)((float)MinVSyncBP/HPeriodEst))+1;
if(VSyncBP<(VSync+MinVBPorch))
{
VSyncBP=VSync+MinVBPorch;
}
VBackPorch= VSyncBP-VSync;
VTotal=VLinesRnd+TopMargin+BottomMargin+VSyncBP+MinVPorchRnd;
// Find ideal duty cycle from formula
IdealDutyCycle=CPrime-(MPrime*HPeriodEst/1000.0);
if(IdealDutyCycle<20)
{
HBlank=( (int) (TotalActivePixels * 20.0/ 80 / (2 * CellGranRnd) )) * 2 * CellGranRnd;
}
else
{
HBlank=( (int) (TotalActivePixels * IdealDutyCycle / (100.0-IdealDutyCycle) / (2 * CellGranRnd) )) * 2 * CellGranRnd;
}
TotalPixels=TotalActivePixels+HBlank;
ActPixelFreq=ClockStep*(int)((float)TotalPixels/(float)HPeriodEst/ClockStep);
ActHFreq=1000*ActPixelFreq/TotalPixels;
ActFieldRate=(1000*ActHFreq)/VTotal;
HSyncRnd=(int)(HSyncPer/100.0*(float)TotalPixels/(float)CellGranRnd)*CellGranRnd;
HBackPorch=HBlank/2;
HFrontPorch=HBlank-HBackPorch-HSyncRnd;
psTiming->wHFP=HFrontPorch;
psTiming->wHSync=HSyncRnd;
psTiming->wHBP=HBackPorch;
psTiming->wHLB=LeftMargin;
psTiming->wHRB=RightMargin;
psTiming->wVFP=MinVPorchRnd;
psTiming->wVSync=VSync;
psTiming->wVBP=VBackPorch;
psTiming->dwClockHz=(DWORD)(ActPixelFreq*1000*1000);
psTiming->dwLineHz=(DWORD)(ActHFreq*1000);
psTiming->bHSync=0; // Set negative
psTiming->bVSync=1; // Set positive to indicaite CRT based cvt timing.
psTiming->wHActive=wXRes;
psTiming->wVActive=wYRes;
psTiming->wRefreshHz=wRefreshRate;
psTiming->wVBB=BottomMargin;
psTiming->wVTB=TopMargin;
}
else // Reduced blanking timings.
{
HBlank=RBHBlank;
HPeriodEst=((1000000.0/VFieldRateRqd)-RBMinVBlank)/(VLinesRnd+TopMargin+BottomMargin);
VBILines= (int)((float)RBMinVBlank/(float)HPeriodEst)+1;
RBMinVBI=RBVFPorch+VSync+MinVBPorch;
if(VBILines<RBMinVBI)
{
ActVBILines=RBMinVBI;
}
else
{
ActVBILines=VBILines;
}
VTotal=ActVBILines+VLinesRnd+TopMargin+BottomMargin;
TotalPixels=TotalActivePixels+HBlank;
ActPixelFreq=ClockStep*(int)((float)VFieldRateRqd*VTotal*TotalPixels/1000000/ClockStep);
ActHFreq=1000*ActPixelFreq/TotalPixels;
ActFieldRate=(1000*ActHFreq)/VTotal;
HBackPorch=HBlank/2;
HFrontPorch=HBlank-HBackPorch-RBHSyncRnd;
psTiming->wHFP=HFrontPorch;
psTiming->wHSync=RBHSyncRnd;
psTiming->wHBP=HBackPorch;
psTiming->wHLB=LeftMargin;
psTiming->wHRB=RightMargin;
psTiming->wVFP=RBVFPorch;
psTiming->wVSync=VSync;
psTiming->wVBP=ActVBILines-(RBVFPorch+VSync);
psTiming->dwClockHz=(DWORD)(ActPixelFreq*1000*1000);
psTiming->dwLineHz=(DWORD)(ActHFreq*1000);
psTiming->bHSync=1; // Set negative
psTiming->bVSync=0; // Set positive to indicaite CRT based cvt timing.
psTiming->wHActive=wXRes;
psTiming->wVActive=wYRes;
psTiming->wRefreshHz=wRefreshRate;
psTiming->wVBB=BottomMargin;
psTiming->wVTB=TopMargin;
}
// we should fill in the other bits and pieces.
psTiming->eDisplayUpdate=PDP_FULL_REFRESH;
psTiming->wUpdateWait=0;
psTiming->bFullRateSyncs=TRUE;
psTiming->bFullRateInterrupts=TRUE;
psTiming->dwBacklightPeriod=10000;
psTiming->bLineDouble=FALSE;
psTiming->bPixelDouble=FALSE;
return PDP_ERROR_OK;
}
/*****************************************************************************
FUNCTION : PDPConstructModeTable
Description: Creates a mode table for the given panel
PARAMETERS :
RETURNS : PDP_ERROR_OK
*****************************************************************************/
PDP_ERROR PDPConstructModeTable(PDP_TIMINGSELECT eMethod,PPDP_EnumerateModesList psModeEnum)
{
switch (eMethod)
{
case PDP_CVT:
// What do we do here?
break;
case PDP_CVT_REDUCED:
// What do we do here?
break;
case PDP_DMT:
return ConstructEnumTable(asDMTTimings,sizeof(asDMTTimings)/sizeof(PDP_TIMINGS),psModeEnum);
break;
case PDP_SHARP_LQ057Q3DC02: // Sharp custom timings
return ConstructEnumTable(asLQ057Q3DC02Timings,sizeof(asLQ057Q3DC02Timings)/sizeof(PDP_TIMINGS),psModeEnum);
break;
case PDP_SHARP_LQ022B2DB02T: // Sharp custom timings
return ConstructEnumTable(asLQ022B2DB02TTimings,sizeof(asLQ022B2DB02TTimings)/sizeof(PDP_TIMINGS),psModeEnum);
break;
case PDP_TOSHIBA_LTM04C380S: // Toshiba custom timings
return ConstructEnumTable(asLTM04C380STimings,sizeof(asLTM04C380STimings)/sizeof(PDP_TIMINGS),psModeEnum);
break;
case PDP_SHARP_LLT1820H: // Sharp custom timings
return ConstructEnumTable(asLLT1820HTimings,sizeof(asLLT1820HTimings)/sizeof(PDP_TIMINGS),psModeEnum);
break;
case PDP_SHARP_LS047D: // Sharp custom timings
return ConstructEnumTable(asLS047DTimings,sizeof(asLS047DTimings)/sizeof(PDP_TIMINGS),psModeEnum);
break;
case PDP_EPSON_LD22002TB301:
return ConstructEnumTable(asLD22002TB301Timings,sizeof(asLD22002TB301Timings)/sizeof(PDP_TIMINGS),psModeEnum);
break;
}
return PDP_ERROR_OK;
}
/*****************************************************************************
FUNCTION : ConstructEnumTable
Description: Creates a mode table for the given timing table
PARAMETERS :
RETURNS : PDP_ERROR_OK
*****************************************************************************/
PDP_ERROR ConstructEnumTable(PPDP_TIMINGS asTimings,int nSize,PPDP_EnumerateModesList psModeEnum)
{
WORD wIndex;
BYTE byBPP;
WORD wModeIndex=0;
WORD wTemp;
// we support 4 different bitdepths per mode so our output table is 4 times the size of the input one
psModeEnum->wCount=0;
psModeEnum->psModeList = new PDP_EnumTableEntry[nSize*4];
if(psModeEnum->psModeList)
{
psModeEnum->wCount=nSize*4;
for(wIndex=0;wIndex<nSize;wIndex++)
{
for(byBPP=8;byBPP<=32;byBPP+=8)
{
psModeEnum->psModeList[wModeIndex].wXRes =asTimings[wIndex].wXRes;
psModeEnum->psModeList[wModeIndex].wYRes =asTimings[wIndex].wYRes;
psModeEnum->psModeList[wModeIndex].wRefresh=asTimings[wIndex].wRefreshHz;
psModeEnum->psModeList[wModeIndex].byBPP=byBPP;
psModeEnum->psModeList[wModeIndex].wStride=(asTimings[wIndex].wHActive * byBPP) / 8;
if(byBPP==24)
{
// the stride must be a whole number of 48 byte words
wTemp=psModeEnum->psModeList[wModeIndex].wStride/48;
if( (wTemp*48)!=psModeEnum->psModeList[wModeIndex].wStride)
{
psModeEnum->psModeList[wModeIndex].wStride=(wTemp+1)*48;
}
}
// figure out the stride.
// The stride must be a whole number of 16 byte words
// to do this calculate the actual stride and round up if needed.
else
{
wTemp=psModeEnum->psModeList[wModeIndex].wStride/16;
if( (wTemp*16)!=psModeEnum->psModeList[wModeIndex].wStride)
{
psModeEnum->psModeList[wModeIndex].wStride=(wTemp+1)*16;
}
}
// now put it back into pixels
// psModeEnum->psModeList[wModeIndex].wStride=(psModeEnum->psModeList[wModeIndex].wStride * 8)/byBPP;
wModeIndex++;
}
}
}
return PDP_ERROR_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -