📄 modectrl.c
字号:
//---------------------------------------------------------------------------
// 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 + -