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

📄 modectrl.c

📁 terawin的t103 LCD驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------
// Terawins Inc. Company Confidential Strictly Private
//
// $Archive: ModeCtrl.c 702 $
// $Revision: 1.01 $
// $Author: JoannW $
// $Date: 2002/06/18 $
//
// --------------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------------
// Copyright 2002 (c) Terawins Inc.
// This is an unpublished work.
// --------------------------------------------------------------------------
#include <reg51.h>
#include <math.h>
#include "common.h"

#include "Struct.h"
#include "system.h"

#include "SRC_ctrl.h"
#include "TwoWire.h"
#include "T803_Util.h"
#include "TW803Reg.h"
#include "OSDCtrl.h"
#include "CfgDsply.h"
#include "OSDDraw.h"
#include "Display.h"
#include "modetbl.h"
#include "Resolution.h"
#include "MyMath.h"
#include "Global.h"
#include "struct.h"
#ifdef NVRAM
	#include "NVRam.h"
#endif
#include "ModeData.h"
#include "ModeCtrl.h"
#include "Auto.h"
#include "INIT.h"
uWORD	wHPeriodCount;

#ifdef PC_MODE

BOOL ModeDetect(void)
{
	uCHAR	cTotalModes;
	uCHAR	cTotalFound;
	uDWORD  dwModeListMask=0;

	uCHAR cPolarity;

	m_cModeStatus = 0;
	EepPrivate.cAltID = 0xFF;
	EepPrivate.wHOffset = 0;
	EepPrivate.wVOffset = 0;
	m_bAlt = 0;
 	m_wVTotal = 0;
	m_bDosMode = 0;
	m_bDigital=0;
	m_dwBuff[0]=GetInputVSyncXclkCnt();	
	GetModeInfo(&m_wVTotal, &wHPeriodCount, m_dwBuff[0]);
	
	if(m_wVTotal < VTOTAL_MIN || wHPeriodCount > HPERIOD_MAX)
	{
		m_cModeStatus = SYNCERROR;  //unreasonable result, sync error
		return FALSE;
	}
	
	cPolarity=McPolDetect();
		

	m_dwBuff[0] = 0; //Clear Modes List

	m_cBuff[0] = NUMINTERLACED;
	m_cBuff[1] = TOTALMODES;
	EepPrivate.cModeID = m_cBuff[0];
	m_cBuff[2] = EepPrivate.cModeID;
	m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];
	while ((m_wVTotal >= m_pModeDescriptorPtr->wVTotal) && (EepPrivate.cModeID <= m_cBuff[1]))
	{
		if(ModeTable[m_cBuff[2]].wVTotal<m_pModeDescriptorPtr->wVTotal)	m_cBuff[2] = EepPrivate.cModeID;
		EepPrivate.cModeID++;
		m_pModeDescriptorPtr++;
	} 
	m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];
	m_cBuff[3] = EepPrivate.cModeID;
	while ((ModeTable[m_cBuff[3]].wVTotal == m_pModeDescriptorPtr->wVTotal) && (EepPrivate.cModeID <= m_cBuff[1]))
	{
		//if(ModeTable[m_cBuff[3]].wVTotal<m_pModeDescriptorPtr->wVTotal)	
			m_cBuff[3] = EepPrivate.cModeID;
		EepPrivate.cModeID++;
		m_pModeDescriptorPtr++;
	} 	
	EepPrivate.cModeID = --m_cBuff[2];
	m_pModeDescriptorPtr = &ModeTable[m_cBuff[2]];
	while ((ModeTable[m_cBuff[2]].wVTotal == m_pModeDescriptorPtr->wVTotal) && (EepPrivate.cModeID >=0))
	{
		//if(ModeTable[m_cBuff[2]].wVTotal<m_pModeDescriptorPtr->wVTotal)	
			m_cBuff[2] = EepPrivate.cModeID;
		EepPrivate.cModeID--;
		m_pModeDescriptorPtr--;
	} 								  	

	//m_cBuff[3] = EepPrivate.cModeID-1;
	dwModeListMask = 1;
	EepPrivate.cModeID =  m_cBuff[2];
	m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];
	

	//Search through this Lower to Upper Bound range, if the polarity is same, 
	//only keep the mode in the list 

	cTotalModes=0;
	cTotalFound=0;
	m_wBuff[0]=0;
	for (EepPrivate.cModeID = m_cBuff[2]; EepPrivate.cModeID <= m_cBuff[3]; EepPrivate.cModeID++, dwModeListMask<<=1, m_pModeDescriptorPtr++)
	{
		if(cPolarity==(m_pModeDescriptorPtr->cModeFlags0& SYNC_POLARITY)) 
		{
			if(cTotalFound==0)
			{
				cTotalFound ++;
				m_dwBuff[1] = dwModeListMask;
        		m_cBuff[0]=EepPrivate.cModeID;	//New Lower Bound
			}
			else
			{
        		m_dwBuff[1] |= dwModeListMask;
				cTotalFound++;
			}			
		}
	}
	cTotalModes = cTotalFound;
	if(cTotalFound==0)	return FALSE;
	EepPrivate.cModeID = m_cBuff[0];    //Move to new lower bound
	m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];
	m_dwBuff[0] = m_dwBuff[1];
	m_dwBuff[1] = 0; 

	//For each remaining mode find the mode with the lowest accuracy value
	if (cTotalModes > 1)
	{
		m_wBuff[0] = 0xffff;
		dwModeListMask = 1L;
		dwModeListMask <<= (EepPrivate.cModeID - m_cBuff[2]);
		cTotalFound = 0;
		//start from new lower bound
		for (EepPrivate.cModeID = m_cBuff[0]; EepPrivate.cModeID <= m_cBuff[3]; EepPrivate.cModeID++, dwModeListMask <<=1, m_pModeDescriptorPtr++)
		{
			if (m_dwBuff[0] & dwModeListMask)
			{
				if (abs( (unsigned int)(m_pModeDescriptorPtr->wVTotal - m_wVTotal)) <=VLINE_TOLERANCE
				   && abs((unsigned int)(m_pModeDescriptorPtr->wHPeriodCount - wHPeriodCount))
					   <=m_pModeDescriptorPtr->wHPeriodCount*HSYNC_TOLERANCE)   
				{
					if ((m_wBuff[1] = (abs((unsigned int)(m_pModeDescriptorPtr->wVTotal - m_wVTotal)))*32 +
 			    		 					(abs((unsigned int)(m_pModeDescriptorPtr->wHPeriodCount - wHPeriodCount))))
						<= m_wBuff[0])
					{
						if (m_wBuff[1]==m_wBuff[0])
						{
							m_dwBuff[1] |= dwModeListMask;
							cTotalFound++;
						}
						else
						{
							cTotalFound = 1;
							m_dwBuff[1] = dwModeListMask;
							m_wBuff[0] = m_wBuff[1];
							m_cBuff[0] = EepPrivate.cModeID;  //New Lower Bound
						}
					}
				}
			}
		}
		if(cTotalFound==0)   //Error
		{
			EepPrivate.cModeID = m_cBuff[0];
			m_cModeStatus = OVERRANGE;
			return FALSE;
		}
		else
			cTotalModes = cTotalFound;
	}
	EepPrivate.cModeID = m_cBuff[0];
	m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];
	m_dwBuff[0] = m_dwBuff[1];
	m_dwBuff[1] = 0;
	
	//If still more than 1 mode left, for each remaining mode find the mode with closest HPeriod
	//If only one mode left, mode detect done
	if (cTotalModes > 1)
	{
		m_wBuff[0] = 0xffff;
		dwModeListMask = 1;
		dwModeListMask <<= (EepPrivate.cModeID - m_cBuff[2]);
		cTotalFound = 0;
		for (EepPrivate.cModeID = m_cBuff[0]; EepPrivate.cModeID <= m_cBuff[3]; EepPrivate.cModeID++, dwModeListMask<<=1, m_pModeDescriptorPtr++)
		{
			if (m_dwBuff[0] & dwModeListMask)
			{
				if (m_wBuff[1] = (abs(m_pModeDescriptorPtr->wHPeriodCount - wHPeriodCount)) <= m_wBuff[0])
				{
					if (m_wBuff[1]==m_wBuff[0])
					{
						m_dwBuff[1] |= dwModeListMask;
						cTotalFound++;
					}
					else
					{
						cTotalFound = 1;
						m_dwBuff[1] = dwModeListMask;
						m_wBuff[0] = m_wBuff[1];
						m_cBuff[0] = EepPrivate.cModeID;
					}
				}
			}
		}
		cTotalModes = cTotalFound;
	} 
	

	EepPrivate.cModeID = m_cBuff[0];
	m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];
	m_dwBuff[0] = m_dwBuff[1];
	m_dwBuff[1] = 0;
	
	if (cTotalModes > 1)
	{
		m_wBuff[0] = 0xffff;
		cTotalFound =  0;
		dwModeListMask = 1;
		dwModeListMask <<= (EepPrivate.cModeID - m_cBuff[2]);
		for (EepPrivate.cModeID = m_cBuff[0]; EepPrivate.cModeID <= m_cBuff[3]; EepPrivate.cModeID++, dwModeListMask <<= 1, m_pModeDescriptorPtr++)
		{
			if (m_dwBuff[0] & dwModeListMask)
			{
				m_cBuff[1] = m_pModeDescriptorPtr->cResID;
				m_pResolutionPtr = &ResolutionTable[m_cBuff[1]];
				if ((m_wBuff[1]=abs(m_pResolutionPtr->wVRes-m_wVRes)) <= m_wBuff[0])
				{
					if (m_wBuff[1] == m_wBuff[0])
					{
						m_dwBuff[1] |= dwModeListMask;
						cTotalFound++;
					}
					else
					{
						cTotalFound = 1;
						m_dwBuff[1] = dwModeListMask;
						m_wBuff[0] = m_wBuff[1];
						m_cBuff[0] = EepPrivate.cModeID;
					}
				}
			}
		}
		cTotalModes = cTotalFound;
	}

	//If there are still two or more equidistant modes, then choose the first one
	EepPrivate.cModeID = m_cBuff[0]; 
	m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];                     
	
	m_cModeStatus = MODEFOUND;
	if(m_pModeDescriptorPtr->cModeFlags1 & bDosMode)
	{
		m_cModeStatus |= DOSMODE;
		m_bDosMode = 1;
	}
	
	
	//If there are alternate HTotals
	if (m_pModeDescriptorPtr->cModeFlags2 & bAltHTotal)
	{
		SearchAltMode();
	}
		
	if(m_bAlt)
	{
		m_pAltHTotalPtr = &AltHTotals[EepPrivate.cAltID];
		EepPrivate.wHTotal = m_pAltHTotalPtr->wHTotal;
		m_cBuff[0] = m_pAltHTotalPtr->cResID;
		m_pResolutionPtr = &ResolutionTable[m_cBuff[0]];
		if(m_pAltHTotalPtr->cModeFlags & bSubSample)
			m_cModeStatus |= ADCHIGHRANGE;
		else if(m_pAltHTotalPtr->cModeFlags & bDoubSample)
			m_cModeStatus |= ADCLOWRANGE;
	}
	else
	{
		EepPrivate.wHTotal = m_pModeDescriptorPtr->wHTotal;
  		m_cBuff[0] = m_pModeDescriptorPtr->cResID;
		m_pResolutionPtr = &ResolutionTable[m_cBuff[0]];
		if(m_pModeDescriptorPtr->cModeFlags1 & bSubSample)
			m_cModeStatus |= ADCHIGHRANGE;
		else if(m_pModeDescriptorPtr->cModeFlags1 & bDoubSample)
			m_cModeStatus |= ADCLOWRANGE;
	}
		
    if(m_cModeStatus==MODEFOUND)
		m_cModeStatus |= NORMALMODE;

	return TRUE;
}
// ================================================================
//	Sync_Mode_Detect			Kevin Hsu.	Mar. 2th, 2006
// ================================================================
//	Description: Detect what kind of Sync. in VGA signal. 
//	Output:		 m_Synctype : VGA sync. type.
//	---------------------------------------------------------------
void Sync_Mode_Detect(void)
{
	int i;

	//~ Enable Sync exist detect ~//
	I2CWriteByte(TW803_P0, 0x21, 0x04);
	
	//~ Wait for Checking HS/VS finish. ~//
	i=300;
	while(i)
	{
		twdDelay(10);
		i--;
		if(I2CReadByte(TW803_P0, 0x21)&0x04)
			break;
	}
	//~ Check if HS and VS is exist. ~//
	if((I2CReadByte(TW803_P0, 0x21)&0x03)==3)	//~ Synchronize is possible the Composite type or Separate type. ~//
	{
		
		//~ Set up HS/VS polarity. We set it as auto-adjusting. ~//
		I2CWriteByte(TW803_P0,0x10,0x19);
		//~ Suppose	that sync. is Composite type and setup its route. ~//
		m_Synctype=Sync_CS;
		I2CWriteByte(TW803_P0,0x14,0x65);
		twdDelay(500);
		//~ Enable CSync detect and XCLK ~//
	/*	I2CWriteByte(TW803_P0,0x13,0x22);
		twdDelay(1000);
		
		if(I2CReadByte(TW803_P0, 0x13)&0x80) //~ Check CSync detection is done or not. ~//
		{
			//~ If true, sync is Composite type. ~//
			m_Synctype=Sync_CS;
		}
		else							     //~ Sync. is Separate type. ~//
		{*/
			//~ Setup Separate type. ~// 	  			
			m_Synctype=Sync_SS;  
			//~ Setup Separate type route. ~// 
			I2CWriteByte(TW803_P0,0x14,0xF0);
		
		//}  
	}
	else  									 //~ No HS and VS, we suppose that synchronize is SOG type. ~//
	{	
		//~ Setup SOG/SOY type. ~//
		m_Synctype=Sync_SOG;  
		//~ Set up SOG/SOY  polarity. We set it as non-invert. ~//
		I2CWriteByte(TW803_P0,0x10,0x39);
		//~ Setup SOG/SOY  type route. ~//
		I2CWriteByte(TW803_P0,0x11,0x20);
		I2CWriteByte(TW803_P0,0x12,0xef);
		I2CWriteByte(TW803_P0,0x14,0x6c);	
	}
	m_cSource = itypeRGB;

}


void SearchAltMode(void)
{
	m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];

	m_cBuff[0] = m_pModeDescriptorPtr->cResID;
	m_pResolutionPtr = &ResolutionTable[m_cBuff[0]];

	if(m_pModeDescriptorPtr->cModeFlags1 & bSubSample)
	{
		SetModeCaptureData(m_pModeDescriptorPtr->wHTotal/2, (m_pModeDescriptorPtr->wHBlk-HOFFSETPW-HOFFSET_MIN)/2,
        	(m_pModeDescriptorPtr->cVBlk-VSGEPW),m_pModeDescriptorPtr->cModeFlags2);
	}
	else if(m_pModeDescriptorPtr->cModeFlags1 & bDoubSample)
	{
		SetModeCaptureData(m_pModeDescriptorPtr->wHTotal*2, (m_pModeDescriptorPtr->wHBlk-HOFFSETPW-HOFFSET_MIN)*2,
        	(m_pModeDescriptorPtr->cVBlk-VSGEPW),m_pModeDescriptorPtr->cModeFlags2);
	}
	else
	{
		SetModeCaptureData(m_pModeDescriptorPtr->wHTotal,(m_pModeDescriptorPtr->wHBlk-HOFFSETPW-HOFFSET_MIN),
    		(m_pModeDescriptorPtr->cVBlk-VSGEPW), m_pModeDescriptorPtr->cModeFlags2);
	}

	if ((m_cSource&0x0F)==(isrcANALOG|isrcSOG))
		twdDelay(250);
	else
		twdDelay(350);  //for 3100(802B)
	
	if(!m_bDosMode)
  	{
		GetVResolution();
		if(abs(m_pResolutionPtr->wVRes-m_wVRes) >2)
		{
			m_dwBuff[0] = 0;
			m_bAlt = GetAlternate();
		}	  
		else
		{
			m_wBuff[0] = m_pModeDescriptorPtr->wHTotal; 
			m_dwBuff[0] = GetPhaseDelta(m_wBuff[0]);
			m_bAlt = GetAlternate();      
		}
	}
	else
	{
  		m_wBuff[0] = m_pModeDescriptorPtr->wHTotal; 
		m_dwBuff[0] = GetPhaseDelta(m_wBuff[0]);
		m_bAlt = GetAlternate();
	}	
}

BOOL GetAlternate(void)
{
	m_cBuff[2] = 0xFF;           
	        
	for (m_cBuff[0] = 0; m_cBuff[0] <= ALTHTOTAL; m_cBuff[0]++)
	{
		m_pAltHTotalPtr = &AltHTotals[m_cBuff[0]];
		if (m_pAltHTotalPtr->cModeID == EepPrivate.cModeID)
		{
			if(!m_bDosMode)	//None Dos Mode
			{
				m_cBuff[1] = m_pAltHTotalPtr->cResID;
				m_pResolutionPtr = &ResolutionTable[m_cBuff[1]];
				if ((m_cBuff[3] = abs(m_wVRes - m_pResolutionPtr->wVRes)) < 5)
				{
					if(m_pAltHTotalPtr->cModeFlags & bSubSample)
					{
		    			SetModeCaptureData(m_pAltHTotalPtr->wHTotal/2,(m_pAltHTotalPtr->wHBlk-HOFFSETPW-HOFFSET_MIN)/2,
											(m_pAltHTotalPtr->cVBlk-VSGEPW),m_pAltHTotalPtr->cModeFlags);
					}
					else if(m_pAltHTotalPtr->cModeFlags & bDoubSample)
					{
		    			SetModeCaptureData(m_pAltHTotalPtr->wHTotal*2,(m_pAltHTotalPtr->wHBlk-HOFFSETPW-HOFFSET_MIN)*2,
											(m_pAltHTotalPtr->cVBlk-VSGEPW),m_pAltHTotalPtr->cModeFlags);
					}
					else
					{
					SetModeCaptureData(m_pAltHTotalPtr->wHTotal,(m_pAltHTotalPtr->wHBlk-HOFFSETPW-HOFFSET_MIN),
										(m_pAltHTotalPtr->cVBlk-VSGEPW), m_pAltHTotalPtr->cModeFlags);
					}

					twdDelay(300);  //Add for 3100
					m_wBuff[0] = m_pAltHTotalPtr->wHTotal; 
					m_dwBuff[1] = GetPhaseDelta(m_wBuff[0]);
					//Keep bigger one
					if(m_dwBuff[0] < m_dwBuff[1])
					{
						m_dwBuff[0] = m_dwBuff[1];
						EepPrivate.cAltID    = m_cBuff[0];
					}
				}
			}
			else				//Dos Mode
			{
        		if(m_pAltHTotalPtr->cModeFlags & bSubSample)
			{
		    		SetModeCaptureData(m_pAltHTotalPtr->wHTotal/2,(m_pAltHTotalPtr->wHBlk-HOFFSETPW-HOFFSET_MIN)/2,
										(m_pAltHTotalPtr->cVBlk-VSGEPW),m_pAltHTotalPtr->cModeFlags);
			}
			else if(m_pAltHTotalPtr->cModeFlags & bDoubSample)
			{
		    		SetModeCaptureData(m_pAltHTotalPtr->wHTotal*2,(m_pAltHTotalPtr->wHBlk-HOFFSETPW-HOFFSET_MIN)*2,
										(m_pAltHTotalPtr->cVBlk-VSGEPW),m_pAltHTotalPtr->cModeFlags);
			}
			else
			{
				SetModeCaptureData(m_pAltHTotalPtr->wHTotal,(m_pAltHTotalPtr->wHBlk-HOFFSETPW-HOFFSET_MIN),
									(m_pAltHTotalPtr->cVBlk-VSGEPW), m_pAltHTotalPtr->cModeFlags);
			}

			twdDelay(300);  //Add for 3100
			m_wBuff[0] = m_pAltHTotalPtr->wHTotal; 
			m_dwBuff[1] = GetPhaseDelta(m_wBuff[0]);
			//Keep bigger one
			if(m_dwBuff[0] < m_dwBuff[1])
			{

⌨️ 快捷键说明

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