⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timing.c

📁 CS架构的多平台的GUI系统
💻 C
字号:
/***************************************************************************    begin                : Sun Oct 12 2003    copyright            : (C) 2003 - 2005 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.                       * *                                                                         * ***************************************************************************/#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 double round (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 = round(GC.cellGran);	c.minPorch = round(GC.minPorch);	c.vSyncRqd = round(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 = round(hPixels / c.cellGran) * c.cellGran;	/* For interlaced mode halve the vertical parameters, and double	 * the required field refresh rate.	 */	if (wantInterlace) {		vLines = round(vLines / 2);		vFieldRate = vFreq * 2;		dotClock = dotClock * 2;		interlace = 0.5;	} else {		vFieldRate = vFreq;		interlace = 0;	}	/* Determine the lines for margins */	if (wantMargins) {		topMarginLines = round(c.margin / 100 * vLines);		botMarginLines = round(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 = round(c.minVSyncBP / hPeriodEst);		} else if (type == gtf_lockHF) {			/* Find the number of lines in vSync + back porch */			vSyncBP = round((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 = round(hPixels * c.margin) / (100 * c.cellGran);		rightMarginPixels = round(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 +			        leftMarginPixels) / dotClock)))) / (2 * c.m)) * 1000;		/* Find the ideal blanking duty cycle */		idealDutyCycle = c.c - ((c.m * idealHPeriod) / 1000);	}	/* Find the number of pixels in blanking time */	hBlankPixels = round((hTotalActivePixels * idealDutyCycle) /	                     ((100 - idealDutyCycle) * 2 * c.cellGran)) * (2 * c.cellGran);	/* Find the total number of pixels */	hTotalPixels = hTotalActivePixels + hBlankPixels;	/* Find the horizontal back porch */	hBackPorch = round((hBlankPixels / 2) / c.cellGran) * c.cellGran;	/* Find the horizontal sync width */	hSyncWidth = round(((c.hSync/100) * hTotalPixels) / c.cellGran) * c.cellGran;	/* Find the horizontal sync + back porch */	hSyncBP = hBackPorch + hSyncWidth;	if (type == gtf_lockPF) {		/* Find the horizontal frequency */		hFreq = (dotClock / hTotalPixels) * 1000;		/* Find the horizontal period */		hPeriod = 1000 / hFreq;		/* Find the number of lines in vSync + back porch */		vSyncBP = round((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;		/* Find the actual vertical field frequency */		vFieldRate = (hFreq / vTotalLines) * 1000;	} else {		if (type == gtf_lockVF) {			/* Find the horizontal frequency */			hFreq = 1000 / hPeriod;		} else if (type == gtf_lockHF) {			/* Find the horizontal frequency */			hPeriod = 1000 / hFreq;		}        	/* Find the pixel clock frequency */		dotClock = hTotalPixels / hPeriod;	}	/* Find the vertical frame frequency */	if (wantInterlace) {		vFreq = vFieldRate / 2;		dotClock = dotClock / 2;	} else {		vFreq = vFieldRate;	}	/* Return the computed frequencies */	t->vFreq = vFreq;	t->hFreq = hFreq;	t->dotClock = dotClock;	/* Determine the vertical timing parameters */	t->h.hTotal = hTotalPixels;	t->h.hDisp = hTotalActivePixels;	t->h.hSyncStart = t->h.hTotal - hSyncBP;	t->h.hSyncEnd = t->h.hTotal - hBackPorch;	t->h.hFrontPorch = t->h.hSyncStart - t->h.hDisp;	t->h.hSyncWidth = hSyncWidth;	t->h.hBackPorch = hBackPorch;	/* Determine the vertical timing parameters */	t->v.vTotal = vTotalLines;	t->v.vDisp = vLines;	t->v.vSyncStart = t->v.vTotal - vSyncBP;	t->v.vSyncEnd = t->v.vTotal - vBackPorch;	t->v.vFrontPorch = t->v.vSyncStart - t->v.vDisp;	t->v.vSyncWidth = c.vSyncRqd;	t->v.vBackPorch = vBackPorch;	/* Mark as gtf timing using the sync polarities */	t->interlace = (wantInterlace) ? 'I' : 'N';	t->hSyncPol = '-';	t->vSyncPol = '+';}void fb_timing_set (s_server_conf_t *cfg, struct fb_var_screeninfo *v_scr){	gtf_timings t;	int interlace = 0;	double freq = 150;	double xPixels = v_scr->xres;	double yPixels = v_scr->yres;        while (1) {		gtf_calcTimings(xPixels, yPixels, freq, gtf_lockPF, 0, interlace, &t);		if ((t.vFreq > cfg->monitor.vertrefresh_min) && (t.vFreq < cfg->monitor.vertrefresh_max) &&		    (t.hFreq > cfg->monitor.horizsync_min) && (t.hFreq < cfg->monitor.horizsync_max)) {			v_scr->pixclock = 1000000000 / (t.dotClock * 1000);			v_scr->left_margin = t.h.hBackPorch;			v_scr->right_margin = t.h.hFrontPorch;			v_scr->upper_margin = t.v.vBackPorch;			v_scr->lower_margin = t.v.vFrontPorch;			v_scr->hsync_len = t.h.hSyncWidth;			v_scr->vsync_len = t.v.vSyncWidth;			v_scr->sync = FB_SYNC_VERT_HIGH_ACT;			v_scr->vmode = (interlace) ? FB_VMODE_INTERLACED : 0;			return;		}		if (freq-- <= 0) {			debugf(DSER | DFAT, "FBDEV : Unable to get a suitable timing frequency for your monitor");		}	}}#if defined(TESTING_gtf)void main(int argc,char *argv[]){	double xPixels = w;	double yPixels = h;	double freq = 150;	int interlace = 0;	gtf_timings t;	if (argc != 5 && argc != 6) {		printf("Usage: gtfCALC <xPixels> <yPixels> <freq> [[Hz] [KHz] [MHz]] [I]\n");		printf("\n");		printf("where <xPixels> is the horizontal resolution of the mode, <yPixels> is the\n");		printf("vertical resolution of the mode. The <freq> value will be the frequency to\n");		printf("drive the calculations, and will be either the vertical frequency (in Hz)\n");		printf("the horizontal frequency (in KHz) or the dot clock (in MHz). To generate\n");		printf("timings for an interlaced mode, add 'I' to the end of the command line.\n");		printf("\n");		printf("For example to generate timings for 640x480 at 60Hz vertical:\n");		printf("\n");		printf("    gtfCALC 640 480 60 Hz\n");		printf("\n");		printf("For example to generate timings for 640x480 at 31.5KHz horizontal:\n");		printf("\n");		printf("    gtfCALC 640 480 31.5 KHz\n");		printf("\n");		printf("For example to generate timings for 640x480 with a 25.175Mhz dot clock:\n");		printf("\n");		printf("    gtfCALC 640 480 25.175 MHz\n");		printf("\n");		exit(1);	}	/* Get values from command line */	xPixels = atof(argv[1]);	yPixels = atof(argv[2]);	freq = atof(argv[3]);	interlace = ((argc == 6) && (argv[5][0] == 'I'));	/* Compute the CRTC timings */	if (toupper(argv[4][0]) == 'H') {		gtf_calcTimings(xPixels, yPixels, freq, gtf_lockVF, 0, interlace, &t);	} else if (toupper(argv[4][0]) == 'K') {		gtf_calcTimings(xPixels, yPixels, freq, gtf_lockHF, 0, interlace, &t);	} else if (toupper(argv[4][0]) == 'M') {		gtf_calcTimings(xPixels, yPixels, freq, gtf_lockPF, 0, interlace, &t);	} else {		printf("Unknown command line!\n");		exit(1);	}	/* Dump summary info to standard output */	printf("CRTC values for %.0fx%.0f @ %.2f %s\n", xPixels, yPixels, freq, argv[4]);	printf("\n");	printf("  hTotal      = %-4d    vTotal      = %-4d\n",		t.h.hTotal, t.v.vTotal);	printf("  hDisp       = %-4d    vDisp       = %-4d\n",		t.h.hDisp, t.v.vDisp);	printf("  hSyncStart  = %-4d    vSyncStart  = %-4d\n",		t.h.hSyncStart, t.v.vSyncStart);	printf("  hSyncEnd    = %-4d    vSyncEnd    = %-4d\n",		t.h.hSyncEnd, t.v.vSyncEnd);	printf("  hFrontPorch = %-4d    vFrontPorch = %-4d\n",		t.h.hFrontPorch, t.v.vFrontPorch);	printf("  hSyncWidth  = %-4d    vSyncWidth  = %-4d\n",		t.h.hSyncWidth, t.v.vSyncWidth);	printf("  hBackPorch  = %-4d    vBackPorch  = %-4d\n",		t.h.hBackPorch, t.v.vBackPorch);	printf("\n");	printf("  Interlaced  = %s\n", (t.interlace == 'I') ? "Yes" : "No");	printf("  H sync pol  = %c\n", t.hSyncPol);	printf("  V sync pol  = %c\n", t.vSyncPol);	printf("\n");	printf("  Vert freq   = %.2f Hz\n", t.vFreq);	printf("  Horiz freq  = %.2f KHz\n", t.hFreq);	printf("  Dot Clock   = %.2f Mhz\n", t.dotClock);	fprintf(stderr,"Modeline %c%ix%i@%.0f%c %.3f %i %i %i %i %i %i %i %i %s %chsync %cvsync\n",		'"',t.h.hDisp, t.v.vDisp, t.vFreq,'"',		t.dotClock,		t.h.hDisp,		t.h.hSyncStart,		t.h.hSyncEnd,		t.h.hTotal,		t.v.vDisp,		t.v.vSyncStart,		t.v.vSyncEnd,		t.v.vTotal,		(t.interlace == 'I') ? "Interlace" : "",		t.hSyncPol,		t.vSyncPol);}#endif  /* TESTING */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -