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

📄 sync.c

📁 NT68617源程序代码集合
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
********************************************************************************
*
*	                                LCD控制程序
*
*	                          这是一个同步信号处理模块
*
*	文件名	: SYNC.C
*	设计者	: Terry
********************************************************************************
*                                   功 能 描 述
*
*		目前采用的是查询方式的同步信号处理
********************************************************************************
*/
#include "global.h"
#include "scalar.h"
#include "osd.h"
#if EN_85HZ_FRAME_RATE
#include "mode_85.h"
#else
#include "mode.h"
#endif

static void   SyncSetInterlace(void);
static void   SyncGetModePixels(void);
static uint8  SyncGetIndex(void);
static void   SyncOutRelPar(void);
static void   SyncOutOneTimePar(void);
static uint16 SyncGetHcnt(void);
static uint16 SyncGetVcnt(void);
static uint8  SyncGetPol(void);
static void   SyncGetAttr(SYNCATTR * Sync);
static void   SyncSetVsErrRange(uint16 Vcount);
static void   SyncSetHsErrRange(uint16 Hcount);
static uint16 SyncGetVcnt(void);
static void   SyncEnterSleep(void);
static void   SyncSetCapture(void);

/*
********************************************************************************
*		同步信号处理模块参数的定义
********************************************************************************
*/
#define NOPOL					0x80		// 忽略同步信号极性
#define SYNC_VGA_RETRY			6			// 在VGA条件下等待同步信号稳定的次数
#define SYNC_VIDEO_RETRY		6			// 在VIDEO条件下等待同步信号稳定的次数
#define SYNC_DETTIME			50			// 清除同步标志到标志建立需延时的时间,单位毫秒
#define VGA_HTOLE				2			// VGA输入条件下,显示模式变化的水平计数值门限
#define VGA_VTOLE				2			// VGA输入条件下,显示模式变化的水平计数值门限


/*================================= END ======================================*/


SYNCATTR xdata SyncAttr={123,456,0};
bit Flg_Interlace = 0;			// (0)表示逐行扫描; (1)表示隔行扫描
bit Flg_SyncInt = 0;			// 如果等于1表示有同步处理需求的中断产生
uint16 xdata Hfre,Vfre,Vtotal;
uint16 DispModeWidth, DispModeHeight;
uint8 ModeState;

/*
********************************************************************************
* 	函 数 名: SyncSetInterlace
* 	功能描述: 检测当前同步扫描方式是隔行扫描还是逐行扫描,并建立反映扫描方式的
*             标记以及相应寄存器的设置。
* 	输    入: 无
* 	返    回: 无
*   注    意: 目前完成的处理是针对图形输入接口的,对视频输入的情况没有进行处理
********************************************************************************
*/
static void SyncSetInterlace(void)
{
	uint8 i, CountI, CountNI;
	
	WrScalarReg(rP199, 0x03);
	CountI = 0;
	CountNI = 0;
	for (i = 0; i < 5; i++)  {
		if (RdScalarReg(rP19A) & 0x04) CountI++;
		else CountNI++;
		Delay(30);
		}
	if (CountI > CountNI)  {
		WrScalarRegBit(rP020, 0x04, 0x04);
		SyncAttr.HVPol |= 0x08;
		Flg_Interlace = 1;
		}
	else {
		WrScalarRegBit(rP020, 0x00, 0x04);
		SyncAttr.HVPol &= 0xF7;
		Flg_Interlace = 0;
		}
}


/*
********************************************************************************
* 	函 数 名: SyncGetIndex
* 	功能描述: 搜索内建数据表ModeAttr,判断当前显示模式符合内建的哪一个
*			  显示模式
* 	输    入: 无
* 	返    回: 返回数据表的索引
********************************************************************************
*/
static uint8 SyncGetIndex(void)
{
	uint8 mode;
	uint8 num;

	Flg_ModeDetectContinue = 1;

	num = EN_M640X350_50 + EN_M640X350_60 + EN_M640X350_70 + 
		EN_M640X350_85 + EN_M640X400_50 + EN_M640X400_60 + EN_M640X400_70 + EN_M640X400_85;

	//SysPar.Flag &= ~FLAG_720MODE;
#if EN_720MODE
#else
	SysPar.Flag |= FLAG_720MODE;
#endif

	mode = 0;
	while (ModeAttr[mode].Hscnt != 0)  
	{
		if (((ModeAttr[mode].Pol&NOPOL) || ((ModeAttr[mode].Pol&0x03) == SyncAttr.HVPol)) &&
			(abs(SyncAttr.Hcount - ModeAttr[mode].Hscnt) <= ModeAttr[mode].HErr) &&
			(abs(SyncAttr.Vcount - ModeAttr[mode].Vscnt) <= ModeAttr[mode].VErr))  
		{
#if 0
#if USE_MODE_GLS	//解决848x480/60Hz与640x480/60 被识别为同一模式的方法 // chen 08-05-23
#if EN_M848X480_60
			if((uint8)(Hfre/100)>30 && (uint8)(Hfre/100)<32 && ((uint8)((Vfre+50)/100) == 60))
			{
				if(Flg_ModeDetectContinue)
				{
					if(Vtotal > 520)	
					{
						mode++;
						Flg_ModeDetectContinue = 0;
						continue;
					}
				}
			}
#endif
#endif
#endif

#if EN_720MODE
			if(SysPar.Flag & FLAG_720MODE)
			{
#endif
				if (mode >= 2 && mode < num + 2)  
				{
					if (SysPar.Flag & FLAG_720MODE)  mode += num;
				}
#if EN_720MODE
			}
#endif
			return mode;
		}
		mode++;
	}
	return 0xFF;
}


/*
********************************************************************************
* 	函 数 名: SyncGetModePixels
* 	功能描述: 获取当前显示模式的的水平和垂直像素
* 	输    入: 该显示模式的索引号
* 	返    回: 无
********************************************************************************
*/
void SyncGetModePixels(void)
{
	if (ModePar.mode != 0xFF)  {
		DispModeWidth = ModeAttr[ModePar.mode].Hdisp;
		DispModeHeight = ModeAttr[ModePar.mode].Vdisp;
		}
	else {
		DispModeWidth = 1024;
		DispModeHeight = 768;
		}
}


uint32 SyncGetHscnt(void)
{
	uint32 hcnt;

	hcnt = RdScalarWord(rP0DE);
	hcnt <<= 8;
	hcnt += RdScalarReg(rP0DD);

	return hcnt;
}


/*
********************************************************************************
* 	函 数 名: SyncOutRelPar
* 	功能描述: 当显示模式稳定后,输出该显示模式相关的参数, 这里所输出的参数是当模
*             式变化时,必须去输出的参数,系统开机之后仅需要输出一次的参数则放
*             到另一个函数中去处理
* 	输    入: 该显示模式的索引号
* 	返    回: 无
********************************************************************************
*/
static void SyncOutRelPar(void)
{
	uint16 dstVtotal,dstHtotal;
	uint16 DispActiveHeight;
	uint8 val;
	xdata float temp;


	if (Flg_Interlace)  {
		if (DispModeWidth > 750) WrScalarReg(rP199, 0x03);
		else WrScalarReg(rP199, 0x01);
		}
	
	val = 0x04;

	if (DispModeWidth >= PanelWidth) val |= 0x40;
	if (DispModeHeight >= PanelHeight) val |= 0x80;
	WrScalarReg(rP191, val);		//rP191在NT68167中没有定义,而该值的6,7位会影响图象以及功耗。// chen 08-05-08

	//	设置捕获窗口的宽度、宽度和位置
	if (Flg_Interlace) WrScalarWord(rP032, DispModeHeight<<1);
	else WrScalarWord(rP032, DispModeHeight);
	WrScalarWord(rP036, DispModeWidth);
	AdjHpos(HIDE, 0);
	AdjVpos(HIDE, 0);
	
/*
================================================================================
=		输出和SCALAR输出部分相关的参数
================================================================================
*/
	//	以kHz为单位计算输出的点时钟频率
	ulDotClk = (((uint32)PanelHeight * Vtotal)/DispModeHeight) * ((uint32)Vfre/10) * PanelMinHTotal / 10000;		// 单位是kHz
	if (Flg_Interlace)  ulDotClk = ulDotClk << 1;			// 如果是隔行方式, 则将时钟加倍

	DispActiveHeight = PanelHeight;		// 如果是满屏显示,那么可以这么处理
	dstHtotal = PanelMinHTotal;
	
	//	计算输出的垂直所有像素
	dstVtotal = ((((uint32)Vtotal * DispActiveHeight) << 4) / DispModeHeight + 8) >> 4;	//add .5 for rounding, make even	
	if (Flg_Interlace)  dstVtotal = dstVtotal << 1;
	if (dstVtotal < PanelMinVTotal) dstVtotal = PanelMinVTotal;
	else if (dstVtotal > PanelMaxVTotal) dstVtotal = PanelMaxVTotal;

	// 对ulDotClk的范围进行校正
	// 这里先不进行处理
	if (ulDotClk < PanelMinPClk)  dstHtotal = PanelTypHTotal;

	WrScalarWord(rP164, DispActiveHeight);
	WrScalarWord(rP171, DispActiveHeight);
	
	// 重新计算ulDotClk, 前面的值仅仅是一个预估值
	temp = (((float)dstHtotal-0.1) * DispActiveHeight * 4096) / ulHfreqCounter / DispModeHeight;
	ulDotClk = (uint32)(temp * 12000000);
	
	SarSetDPLL();
	
	WrScalarWord(rP15B, dstVtotal);		// Display Vertical Total
	WrScalarWord(rP15E, dstHtotal);		// Display Horixontal Total
}


/*
********************************************************************************
* 	函 数 名: SyncOutOneTimePar
* 	功能描述: 当显示模式稳定后,输出该显示模式相关的参数
* 	输    入: 该显示模式的索引号
* 	返    回: 无
********************************************************************************
*/
static void SyncOutOneTimePar(void)
{
/*
================================================================================
=		亮度和颜色部分的参数输出
=		需要注意的是: 红绿蓝增益的部分,在对比度的输出中已经输出,因为他们都是
=	通过sRGB的方式来输出的
================================================================================
*/
	AdcUpdatePara(&AdcPar);

	AdjBacklight(HIDE, 0);
	AdjBri(HIDE, 0);
	AdjCon(HIDE, 0);

/*
================================================================================
=		输出其他部分的参数
================================================================================
*/
#if USE_AUDIO
	AdjMute(HIDE, 0);
	AdjVolume(HIDE, 0);
#endif

/*
================================================================================
=	滤波器设置和BF3的亮度/对比度/饱和度设置
================================================================================
*/
	if ((InputSource == SOURCE_VGA ) ||(InputSource == SOURCE_DVI_A)) {
		WrScalarReg(rP068, 0x7A);
//		WrScalarReg(rP06A, 0xD1);
		WrScalarReg(rP06A, 0x00);	// 08-05-09
		SarBF3Bri(0x80);
		SarBF3Con(0x80);
		SarBF3Sat(0x80);
		}
		
	else if (InputSource == SOURCE_DVI_D)  {
		WrScalarReg(rP068, 0x00);
		WrScalarReg(rP06A, 0x00);
		SarBF3Bri(0x80);
		SarBF3Con(0x80);
		SarBF3Sat(0x80);
		}
	
	else  {
		SarBF3Bri(0x80);
		SarBF3Con(0x90);
		SarBF3Sat(0x90);
		}

	Adj4B3Disp(HIDE, 0);
	AdjCMWindow(HIDE, 0);
}


/*
********************************************************************************
*		与同步处理相关的初始化数据表
********************************************************************************
*/
uint8 code SyncInitTab[] = {
0x04, RegAddr(rP196),
	B0110_1010,				// rP196 Graphic Sync Processor Control 1
	B1100_0000,				// rP197 Graphic Sync Processor Control 2
							//       bit4,bit5在正常的情况下不能置位,会导致显示乱
	0x4C,					// rP198 Interlace Detector Control
	//B0100_0001,				// rP199 Graphic SYNC Processor Control 3
	B0100_0011,				// rP199 // 2006-12-27 修改

//	rP1A3-rP1A6的结果是在时钟频率为12M时计算得来的
0x0A, RegAddr(rP1A3),
	366/8,					// rP1A3 Hsync not present 
	366/15,					// rP1A4 Hsync present
	366/5,					// rP1A5 Vsync not present
	1465/20,				// rP1A6 Vsync present
	0x08,					// rP1A7 Hcounter change threshold
	0x24,					// rP1A8 Vcounter change threshold
	0xBC,					// rP1A9 H/V interrupt enable1
	0x03,					// rP1AA H/V interrupt enable2
	0x3C,					// rP1AB H/V interrupt clear1
	0x03,					// rP1AC H/V interrupt clear2

0x02, RegAddr(rP1AF),
	0x4C,					// rP1AF Video Field Decision Windows
	0x00,					// rP1B0 Field Polarity Control

0x01, RegAddr(rP37A),
	0x41,					// 2006-12-27 添加
	
	0,		// 如果记录长度为0, 那么表示数据表结束
};

/*
********************************************************************************
* 	函 数 名: SyncInit
* 	功能描述: 初始化SCALAR的同步处理
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
void SyncInit(void)
{
	RegDataTableOut(SyncInitTab);
	SelVideoInput(SOURCE_VGA);
	SyncClearIntFlag();					// 清除中断标志
}


/*
********************************************************************************
* 	函 数 名: SyncGetIntState
* 	功能描述: 获取是否有同步终端产生, 设置相应的标志(Flg_SyncInt), 并返回状态
* 	输    入: 无
* 	返    回: 如果有中断产生则返回1, 否则返回0
********************************************************************************
*/
uint8 SyncGetIntState(void)
{
	return Flg_SyncInt;
}


/*
********************************************************************************

⌨️ 快捷键说明

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