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

📄 auto.c

📁 NT68617源程序代码集合
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
********************************************************************************
*
*	                                LCD控制程序
*
*	                          这是一个自动调整处理模块
*
*	文件名	: AUTO.C
*	设计者	: Terry
********************************************************************************
*                                   功 能 描 述
*
*		完成自动调整处理,该自动调整包括:
*       时钟,时钟相位,水平位置,垂直位置
********************************************************************************
*/
#include "global.h"
#include "scalar.h"

#define NOISE_MARGIN			0x30		// 自动位置校正时, 非黑像素的门限值
#define AUTO_MASK				0x40		// 0x40表示Mask Windows Enable, 否则为0x00


uint8 xdata MinSOD_Phase;
uint8 xdata MaxSOD_Phase;
uint8 xdata PhaseSearchRange;


static uint8 AutoTuneAdcGain(void);
static uint8 AutoTuneAdcClamp(void);
static void AutoFineTuneAdcOffset(void);

static uint8 AutoTuneTextModePos(void);
static void  AutoTuneHPos(void);
static uint8 AutoTuneClock(void);
static uint8 AutoTunePhaseByClock(void);
static uint8 AutoTuneClockByPhase(void);
static uint32 AutoCheckPhaseData(void);
static uint8 AutoTunePhaseFine(void);
static uint8 AutoCheckClock(void);
static void AutoGetHmask(void);

ADCPAR code AutoAdcPar = {
	0xFF,
	0x80,
	0xFF,
	0x80,
	0xFF,
	0x80,
};


//	这是一种通过测量RGB的最大和最小值来校正ADC增益和偏压的方法
/*
********************************************************************************
* 	函 数 名: AutoTuneAdc
* 	功能描述: 自动校正三路ADC的增益和钳位
* 	输    入: 无
* 	返    回: 调整的结果: AUTO_OK或者是AUTO_FAIL
*   说    明: 原理还没有搞清楚
********************************************************************************
*/
uint8 AutoTuneAdc(void)
{
	uint8 Reg06A, Reg1BC;

	// 关闭Jitter功能
	Reg06A = RdScalarReg(rP06A);
	Reg1BC = RdScalarReg(rP1BC);
	WrScalarReg(rP06A, 0x00);
	WrScalarReg(rP1BC, 0x00);

/*
================================================================================
=	下面被屏蔽掉的两句是用于调试的,可以观察AUTO COLOR的效果,比较好的结果是,
=	左侧应该是一条白线
================================================================================
*/
	//WrScalarReg(rP1C7, 0x18);		//for debug only
	//WrScalarReg(rP1C8, 0x03);		//for debug only

	if(AutoTuneAdcClamp() == AUTO_FAIL) {
		WrScalarReg(rP06A, Reg06A);
		AdcSetClamp(0, AdcPar.clampR);
		AdcSetClamp(1, AdcPar.clampG);
		AdcSetClamp(2, AdcPar.clampB);
		WrScalarReg(rP1BC, Reg1BC);
		WrScalarReg(rP06A, Reg06A);
		return AUTO_FAIL;
	}

	AutoFineTuneAdcOffset();
	AdcPar.clampR = RdScalarReg(rP003);
	AdcPar.clampG = RdScalarReg(rP006);
	AdcPar.clampB = RdScalarReg(rP009);
	if (AutoTuneAdcGain() == AUTO_FAIL) {
		WrScalarReg(rP06A, Reg06A);
		AdcSetGain(0, AdcPar.gainR);
		AdcSetGain(1, AdcPar.gainG);
		AdcSetGain(2, AdcPar.gainB);
		WrScalarReg(rP1BC, Reg1BC);
		WrScalarReg(rP06A, Reg06A);
		return AUTO_FAIL;
		}
	AdcPar.gainR = RdScalarReg(rP001);
	AdcPar.gainG = RdScalarReg(rP004);
	AdcPar.gainB = RdScalarReg(rP007);
	WrScalarReg(rP06A, Reg06A);
	WrScalarReg(rP1BC, Reg1BC);
	return AUTO_OK;
}


#if 0
/*
********************************************************************************
* 	函 数 名: AutoTuneAdc
* 	功能描述: 自动校正三路ADC的增益和钳位
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
static uint8 AutoTuneAdcGain(void)
{
#define	MinIndex	0
#define	MidIndex	1
#define	MaxIndex	2
#define	Cal_Gain_Loop	8
#define	FinalOffset	4

	uint8 RGB_Gain[3][3],CompareBuf[3],DataBuf,i,j;
	bit Is_Compare_ok;

	CompareBuf[0] = AdcPar.gainR;
	CompareBuf[1] = AdcPar.gainG;
	CompareBuf[2] = AdcPar.gainB;
		
	Is_Compare_ok = 0;
	while(!Is_Compare_ok){
		Is_Compare_ok = 1;
	
		RGB_Gain[MinIndex][0] = 0x00;
		RGB_Gain[MinIndex][1] = 0x00;
		RGB_Gain[MinIndex][2] = 0x00;
		
		RGB_Gain[MaxIndex][0] = 0xFF;
		RGB_Gain[MaxIndex][1] = 0xFF;
		RGB_Gain[MaxIndex][2] = 0xFF;
		
		RGB_Gain[MidIndex][0] = 0x7F;
		RGB_Gain[MidIndex][1] = 0x7F;
		RGB_Gain[MidIndex][2] = 0x7F;

		AdcSetGain(COLOR_R, RGB_Gain[MidIndex][COLOR_R]);
		AdcSetGain(COLOR_G, RGB_Gain[MidIndex][COLOR_G]);
		AdcSetGain(COLOR_B, RGB_Gain[MidIndex][COLOR_B]);

		for(i = 0; i < Cal_Gain_Loop; i++){
			WrScalarReg(rP106, 0x2E);
			SysTmr = 5;
			while((RdScalarReg(rP106) & BIT_1) && SysTmr != 0){
				ClearWatchDog();
				if (SyncGetIntState()) return AUTO_FAIL;
				}
			for(j = 0; j < 3; j++){
				DataBuf = RdScalarReg((rP113 + j));
				if(DataBuf < 254){
					RGB_Gain[MaxIndex][j]=RGB_Gain[MidIndex][j];
					RGB_Gain[MidIndex][j]=((uint16)RGB_Gain[MidIndex][j]+RGB_Gain[MinIndex][j])/2;
					}
				else if(DataBuf == 0xFF){
					RGB_Gain[MinIndex][j]=RGB_Gain[MidIndex][j];
					RGB_Gain[MidIndex][j]=((uint16)RGB_Gain[MaxIndex][j]+RGB_Gain[MidIndex][j])/2;
				}
			}
			AdcSetGain(COLOR_R, RGB_Gain[MidIndex][COLOR_R]);
			AdcSetGain(COLOR_G, RGB_Gain[MidIndex][COLOR_G]);
			AdcSetGain(COLOR_B, RGB_Gain[MidIndex][COLOR_B]);
		}
		
		for(i = 0; i < 3; i++){		//compare data
			if(abs(RGB_Gain[MidIndex][i]-CompareBuf[i])>5){
				CompareBuf[i]=RGB_Gain[MidIndex][i];
				Is_Compare_ok=0;
			}
		}
	}
	AdcSetGain(COLOR_R, RGB_Gain[MidIndex][COLOR_R] - FinalOffset);
	AdcSetGain(COLOR_G, RGB_Gain[MidIndex][COLOR_G] - FinalOffset);
	AdcSetGain(COLOR_B, RGB_Gain[MidIndex][COLOR_B] - FinalOffset);
	return AUTO_OK;
}
#endif


//#if 0
/*
********************************************************************************
* 	函 数 名: AutoTuneAdc
* 	功能描述: 自动校正三路ADC的增益
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
static uint8 AutoTuneAdcGain(void)
{
#define	MinIndex	0
#define	MidIndex	1
#define	MaxIndex	2

	uint8 RGB_Gain[3][3], OutData[3];
	uint8 i, Color;

	RGB_Gain[MinIndex][0] = 0x00;
	RGB_Gain[MinIndex][1] = 0x00;
	RGB_Gain[MinIndex][2] = 0x00;
		
	RGB_Gain[MaxIndex][0] = 0xFF;
	RGB_Gain[MaxIndex][1] = 0xFF;
	RGB_Gain[MaxIndex][2] = 0xFF;
		
	RGB_Gain[MidIndex][0] = 0x7F;
	RGB_Gain[MidIndex][1] = 0x7F;
	RGB_Gain[MidIndex][2] = 0x7F;

	AdcSetGain(COLOR_R, RGB_Gain[MidIndex][COLOR_R]);
	AdcSetGain(COLOR_G, RGB_Gain[MidIndex][COLOR_G]);
	AdcSetGain(COLOR_B, RGB_Gain[MidIndex][COLOR_B]);

	for (i = 0; i < 20; i++)  {
		WrScalarReg(rP106, 0x2E);
		SysTmr = 200/SYSTMR_PRIO;
		while((RdScalarReg(rP106) & BIT_1) && SysTmr != 0)  {
			ClearWatchDog();
			if (SyncGetIntState()) return FALSE;
			}

		for (Color = 0; Color < 3; Color++)  {
			OutData[Color] = RdScalarReg(rP113 + Color);
			if (OutData[Color] == 255)  {
				RGB_Gain[MinIndex][Color] = RGB_Gain[MidIndex][Color];
				RGB_Gain[MidIndex][Color] = ((uint16)RGB_Gain[MinIndex][Color] + RGB_Gain[MaxIndex][Color]) / 2;
				AdcSetGain(Color, RGB_Gain[MidIndex][Color]);
				}
			else if (OutData[Color] < 245)  {
				RGB_Gain[MaxIndex][Color] = RGB_Gain[MidIndex][Color];
				RGB_Gain[MidIndex][Color] = ((uint16)RGB_Gain[MinIndex][Color] + RGB_Gain[MaxIndex][Color]) / 2;
				AdcSetGain(Color, RGB_Gain[MidIndex][Color]);
				}
			else  continue;
			}

		if (OutData[0] >= 245 && OutData[1] >= 245 && OutData[2] >= 245) break;
		}

	if (i >= 20) return FALSE;
	if (OutData[0] < 200 || OutData[1] < 200 || OutData[2] < 200) return FALSE;

	//AdcSetGain(COLOR_R, RGB_Gain[MidIndex][COLOR_R]);
	//AdcSetGain(COLOR_G, RGB_Gain[MidIndex][COLOR_G]);
	//AdcSetGain(COLOR_B, RGB_Gain[MidIndex][COLOR_B]);
	for (i = 0; i < 64; i++)  {
		WrScalarReg(rP106, 0x2E);
		SysTmr = 200/SYSTMR_PRIO;
		while((RdScalarReg(rP106) & BIT_1) && SysTmr != 0)  {
			ClearWatchDog();
			if (SyncGetIntState()) return FALSE;
			}

		for (Color = 0; Color < 3; Color++) {
			OutData[Color] = RdScalarReg(rP113 + Color);
			if (OutData[Color] < 255) {
				RGB_Gain[MidIndex][Color]--;
				AdcSetGain(Color, RGB_Gain[MidIndex][Color]);
				}
			}

		if (OutData[0] == 255 && OutData[1] == 255 && OutData[2] == 255) break;
		//if (OutData[0] >= 254 && OutData[1] >= 254 && OutData[2] >= 254) break;
		}

	if (i >= 64) return FALSE;
	else return TRUE;
}
//#endif

/*
********************************************************************************
* 	函 数 名: AutoTuneAdcClamp
* 	功能描述: 自动校正ADC的钳位
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
static uint8 AutoTuneAdcClamp(void)
{
	uint8 RGB_Offset[3][3],DataBuf,i,j,AutoWay;
	bit Is_Compare_ok;

#define	MinIndex		0
#define	MidIndex		1
#define	MaxIndex		2

#define	Cal_Offset_Loop		8
#define	AutoWayByMask			0x4a
#define	AutoWayByCapture		0x2a

	Is_Compare_ok = 0;
	AutoWay = AutoWayByMask;
	WrScalarRegBit(rP020, 0x00, 0x10);
	if (ModePar.hstart > 0x10) i = ModePar.hstart - 0x10;
	else i = 0;
	WrScalarReg(rP02A, i);
	i = ModePar.htotal - ModePar.hstart - 10;
	WrScalarReg(rP02B, i);
	while(!Is_Compare_ok){
		Is_Compare_ok=1;
		RGB_Offset[MinIndex][0] = 0x00;
		RGB_Offset[MinIndex][1] = 0x00;
		RGB_Offset[MinIndex][2] = 0x00;
		
		RGB_Offset[MaxIndex][0] = 0xFF;
		RGB_Offset[MaxIndex][1] = 0xFF;
		RGB_Offset[MaxIndex][2] = 0xFF;
		
		RGB_Offset[MidIndex][0] = 0x7F;
		RGB_Offset[MidIndex][1] = 0x7F;
		RGB_Offset[MidIndex][2] = 0x7F;
		AdcSetClamp(COLOR_R, RGB_Offset[MidIndex][COLOR_R]);
		AdcSetClamp(COLOR_G, RGB_Offset[MidIndex][COLOR_G]);
		AdcSetClamp(COLOR_B, RGB_Offset[MidIndex][COLOR_B]);
		for(i = 0; i < Cal_Offset_Loop; i++) {
			ClearWatchDog();
			WrScalarReg(rP106, AutoWay);
			SysTmr = 100/SYSTMR_PRIO;
			while((RdScalarReg(rP106) & BIT_1) && SysTmr != 0){
				ClearWatchDog();
				if (SyncGetIntState()) return AUTO_FAIL;
				}
			
			for(j = 0; j < 3; j++){
				DataBuf = RdScalarReg(rP113 + j);
				if(DataBuf > 1){
					RGB_Offset[MinIndex][j]=RGB_Offset[MidIndex][j];			//update min
					RGB_Offset[MidIndex][j]=((uint16)RGB_Offset[MaxIndex][j]+RGB_Offset[MidIndex][j])/2;
				}else if(DataBuf==0){
					RGB_Offset[MaxIndex][j]=RGB_Offset[MidIndex][j];
					RGB_Offset[MidIndex][j]=((uint16)RGB_Offset[MidIndex][j]+RGB_Offset[MinIndex][j])/2;
				}
			}

			AdcSetClamp(COLOR_R, RGB_Offset[MidIndex][COLOR_R]);
			AdcSetClamp(COLOR_G, RGB_Offset[MidIndex][COLOR_G]);
			AdcSetClamp(COLOR_B, RGB_Offset[MidIndex][COLOR_B]);
		}
		
		if(RGB_Offset[MidIndex][1] < 0x10){
		//if(RGB_Offset[MidIndex][1] < 0x08){
			AutoWay = AutoWayByCapture;
			Is_Compare_ok = 0;
		}
	};
	return AUTO_OK;
}


/*
********************************************************************************
* 	函 数 名: AutoFineTuneAdcOffset
* 	功能描述: 通过Novatek新的测量方法来调整钳位,这是通过柱状图的方式来进行
*			  调整处理
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/
void AutoFineTuneAdcOffset(void)
{
#define AutoGaugeWinV_OddBegin  0x0E6
#define AutoGaugeWinV_EvenBegin  0x0E8
#define AutoGaugeWinV_Length  0x0EA
#define AutoGaugeWinH_Begin   0x0EC
#define AutoGaugeWinH_Length  0x0EE

#define Offset   4
#define ShiftLines  10
#define ShiftPixel   25

	uint8 channel,area,ShiftLineBuf,ShiftPixelBuf;
	uint16 xdata H_Start,H_Act,V_Start,V_Act;
	uint32 xdata ExtraBlackPixel,Histogram,Sum;
	bit   TheChannelFineTuneOk;
	
	V_Act = RdScalarWord(rP032) & 0x07FF;
	H_Act = RdScalarWord(rP036) & 0x0FFF;

	V_Start = RdScalarWord(rP02E) & 0x7FF;
	if(V_Start < ShiftLines ) ShiftLineBuf = V_Start;
	else  ShiftLineBuf = ShiftLines;
	
	H_Start = RdScalarWord(rP034) & 0x0FFF;  //H begin
	if(H_Start < ShiftPixel) ShiftPixelBuf = H_Start;
	else  ShiftPixelBuf = ShiftPixel;
	
	if(ShiftPixelBuf > 7 && ShiftLineBuf > 2)
		ExtraBlackPixel = ((ShiftLineBuf-2) * H_Act) + ((ShiftPixelBuf-7)* V_Act);
	else
		ExtraBlackPixel = (ShiftLineBuf * H_Act) + (ShiftPixelBuf* V_Act);
	  
	WrScalarWord(AutoGaugeWinV_OddBegin,(RdScalarWord(rP02E)&0x7FF) -ShiftLineBuf);
	WrScalarWord(AutoGaugeWinV_EvenBegin,(RdScalarWord(rP030)&0x7FF)-ShiftLineBuf);
	WrScalarWord(AutoGaugeWinV_Length,(RdScalarWord(rP032)&0x7FF));
	  
	WrScalarWord(AutoGaugeWinH_Begin,(RdScalarWord(rP034) & 0x0FFF)-ShiftPixelBuf);
	WrScalarWord(AutoGaugeWinH_Length,(RdScalarWord(rP036)& 0x0FFF));
	WrScalarWord(rP0F7, 0x01);		// Gauge Control1 by windows
	WrScalarReg(rP0FA, 0x00);
	  
	for(channel = 0; channel < 3; channel++){   //00-->B,01-->G,10-->R
		TheChannelFineTuneOk = 0;

		while(TheChannelFineTuneOk==0){
			WrScalarReg(rP0F8, 0x00);
	    	WrScalarReg(rP0F8, BIT_7 | (channel<<3));
	    	SysTmr = 100/SYSTMR_PRIO;
	    	Sum = 0;
	       	while((RdScalarReg(rP0F8) & BIT_7) && SysTmr);
			
	    	for(area = 0; area < 8; area++) {
				WrScalarReg(rP0F9, area);
	     		Histogram = RdScalarWord(rP0FC);
	     		Histogram <<= 8;

⌨️ 快捷键说明

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