📄 timing.c
字号:
/*************************************************************************** begin : Sun Oct 12 2003 copyright : (C) 2003 - 2007 by Alper Akcan email : distchx@yahoo.com ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation; either version 2.1 of the * * License, or (at your option) any later version. * * * ***************************************************************************/#if defined(VIDEO_FBDev)#include <math.h>#include "../../../lib/xynth_.h"#include "server.h"#include "../helper/helper.h"#include "fbdev.h"#define gtf_lockVF 1 /* Lock to vertical frequency */#define gtf_lockHF 2 /* Lock to horizontal frequency */#define gtf_lockPF 3 /* Lock to pixel clock frequency */typedef struct { double margin; /* Margin size as percentage of display */ double cellGran; /* Character cell granularity */ double minPorch; /* Minimum front porch in lines/chars */ double vSyncRqd; /* Width of V sync in lines */ double hSync; /* Width of H sync as percent of total */ double minVSyncBP; /* Minimum vertical sync + back porch (us) */ double m; /* Blanking formula gradient */ double c; /* Blanking formula offset */ double k; /* Blanking formula scaling factor */ double j; /* Blanking formula scaling factor weight */} gtf_constants;typedef struct { int hTotal; /* Horizontal total */ int hDisp; /* Horizontal displayed */ int hSyncStart; /* Horizontal sync start */ int hSyncEnd; /* Horizontal sync end */ int hFrontPorch; /* Horizontal front porch */ int hSyncWidth; /* Horizontal sync width */ int hBackPorch; /* Horizontal back porch */} gtf_hCRTC;typedef struct { int vTotal; /* Vertical total */ int vDisp; /* Vertical displayed */ int vSyncStart; /* Vertical sync start */ int vSyncEnd; /* Vertical sync end */ int vFrontPorch; /* Vertical front porch */ int vSyncWidth; /* Vertical sync width */ int vBackPorch; /* Vertical back porch */} gtf_vCRTC;typedef struct { gtf_hCRTC h; /* Horizontal CRTC paremeters */ gtf_vCRTC v; /* Vertical CRTC parameters */ char hSyncPol; /* Horizontal sync polarity */ char vSyncPol; /* Vertical sync polarity */ char interlace; /* 'I' for Interlace, 'N' for Non */ double vFreq; /* Vertical frequency (Hz) */ double hFreq; /* Horizontal frequency (KHz) */ double dotClock; /* Pixel clock (Mhz) */} gtf_timings;static gtf_constants GC = { 1.8, /* Margin size as percentage of display */ 8, /* Character cell granularity */ 1, /* Minimum front porch in lines/chars */ 3, /* Width of V sync in lines */ 8, /* Width of H sync as percent of total */ 550, /* Minimum vertical sync + back porch (us) */ 600, /* Blanking formula gradient */ 40, /* Blanking formula offset */ 128, /* Blanking formula scaling factor */ 20 /* Blanking formula scaling factor weight */};static inline double xround (double v){ return floor(v + 0.5);}/* hPixels - X resolution vLines - Y resolution freq - Frequency (Hz, KHz or MHz depending on type) type - 1 - vertical, 2 - horizontal, 3 - dot clock margins - True if margins should be generated interlace - True if interlaced timings to be generated t - Place to store the resulting timings*/void gtf_calcTimings (double hPixels, double vLines, double freq, int type, int wantMargins, int wantInterlace, gtf_timings *t){ double interlace; double vFieldRate; double hPeriod = 0; double topMarginLines; double botMarginLines; double leftMarginPixels; double rightMarginPixels; double hPeriodEst = 0; double vSyncBP = 0; double vBackPorch = 0; double vTotalLines = 0; double vFieldRateEst; double hTotalPixels; double hTotalActivePixels; double hBlankPixels; double idealDutyCycle = 0; double hSyncWidth; double hSyncBP; double hBackPorch; double idealHPeriod; double vFreq; double hFreq; double dotClock; gtf_constants c; /* Get rounded gtf constants used for internal calculations */ c.margin = GC.margin; c.cellGran = xround(GC.cellGran); c.minPorch = xround(GC.minPorch); c.vSyncRqd = xround(GC.vSyncRqd); c.hSync = GC.hSync; c.minVSyncBP = GC.minVSyncBP; if (GC.k == 0) { c.k = 0.001; } else { c.k = GC.k; } c.m = (c.k / 256) * GC.m; c.c = (GC.c - GC.j) * (c.k / 256) + GC.j; c.j = GC.j; /* Move input parameters into appropriate variables */ vFreq = hFreq = dotClock = freq; /* Round pixels to character cell granularity */ hPixels = xround(hPixels / c.cellGran) * c.cellGran; /* For interlaced mode halve the vertical parameters, and double * the required field refresh rate. */ if (wantInterlace) { vLines = xround(vLines / 2); vFieldRate = vFreq * 2; dotClock = dotClock * 2; interlace = 0.5; } else { vFieldRate = vFreq; interlace = 0; } /* Determine the lines for margins */ if (wantMargins) { topMarginLines = xround(c.margin / 100 * vLines); botMarginLines = xround(c.margin / 100 * vLines); } else { topMarginLines = 0; botMarginLines = 0; } if (type != gtf_lockPF) { if (type == gtf_lockVF) { /* Estimate the horizontal period */ hPeriodEst = ((1/vFieldRate) - (c.minVSyncBP/1000000)) / (vLines + (2*topMarginLines) + c.minPorch + interlace) * 1000000; /* Find the number of lines in vSync + back porch */ vSyncBP = xround(c.minVSyncBP / hPeriodEst); } else if (type == gtf_lockHF) { /* Find the number of lines in vSync + back porch */ vSyncBP = xround((c.minVSyncBP * hFreq) / 1000); } /* Find the number of lines in the V back porch alone */ vBackPorch = vSyncBP - c.vSyncRqd; /* Find the total number of lines in the vertical period */ vTotalLines = vLines + topMarginLines + botMarginLines + vSyncBP + interlace + c.minPorch; if (type == gtf_lockVF) { /* Estimate the vertical frequency */ vFieldRateEst = 1000000 / (hPeriodEst * vTotalLines); /* Find the actual horizontal period */ hPeriod = (hPeriodEst * vFieldRateEst) / vFieldRate; /* Find the actual vertical field frequency */ vFieldRate = 1000000 / (hPeriod * vTotalLines); } else if (type == gtf_lockHF) { /* Find the actual vertical field frequency */ vFieldRate = (hFreq / vTotalLines) * 1000; } } /* Find the number of pixels in the left and right margins */ if (wantMargins) { leftMarginPixels = xround(hPixels * c.margin) / (100 * c.cellGran); rightMarginPixels = xround(hPixels * c.margin) / (100 * c.cellGran); } else { leftMarginPixels = 0; rightMarginPixels = 0; } /* Find the total number of active pixels in image + margins */ hTotalActivePixels = hPixels + leftMarginPixels + rightMarginPixels; if (type == gtf_lockVF) { /* Find the ideal blanking duty cycle */ idealDutyCycle = c.c - ((c.m * hPeriod) / 1000); } else if (type == gtf_lockHF) { /* Find the ideal blanking duty cycle */ idealDutyCycle = c.c - (c.m / hFreq); } else if (type == gtf_lockPF) { /* Find ideal horizontal period from blanking duty cycle formula */ idealHPeriod = (((c.c - 100) + (sqrt((pow(100-c.c,2)) + (0.4 * c.m * (hTotalActivePixels + rightMarginPixels +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -