📄 display.c
字号:
//---------------------------------------------------------------------------
// Terawins Inc. Company Confidential Strictly Private
//
// $Archive: Display.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 "system.h"
#include "Struct.h"
#include "TwoWire.h"
#include "TW101Reg.h"
#include "CfgDsply.h"
#include "Display.h"
uDWORD m_dwTemp[2];
uWORD m_wDWHSZ=DWHSZ;
extern uCHAR idata m_cScaleratio;
extern uCHAR idata m_cBuff[4];
extern uWORD idata m_wBuff[3];
extern uDWORD m_dwBuff[2];
extern uWORD m_wVRes; //as computed, used in output and scaling
extern uWORD m_wHRes; //as computed, used in scaling
extern uWORD idata m_wVTotal;
extern uCHAR idata m_cModeStatus;
extern uCHAR idata m_cSource;
extern uCHAR idata m_cStandard;
//---------------------------------------------------------------------------------
//This is for Display clock set,
//the minimum difference between input freq and out freq should be more than 5MHz
//---------------------------------------------------------------------------------
//----------------------------------------
// Local Definitions for this module
//----------------------------------------
void DisplayProcess(void)
{
uWORD wDVTotal, wDHTotal,wVOffset;
uWORD wDWVSZ, wDVFrac;
uWORD wVibLeft;
uWORD wDHBlk;
float fDHTotalF;
I2CWriteByte(TW101, 0xC2, I2CReadByte(TW101, 0xc2) & 0xFB);
wDWVSZ = DWVSZ; //DWVSZ == Paneal output vertial line number
/////////////////////////Ruby
m_dwBuff[0]=GetInputVSyncXclkCnt();//Read whole frame XCLK counter
m_wBuff[0] = I2CReadByte(TW101, 0x59);
m_wBuff[0] <<= 8;
m_wBuff[0] += I2CReadByte(TW101, 0x58);
m_wVTotal = m_dwBuff[0]*32/m_wBuff[0];
m_dwBuff[1] = I2CReadByte(TW101, 0x83);
m_dwBuff[1] <<= 8;
m_dwBuff[1] = I2CReadByte(TW101, 0x82);
m_dwBuff[1] <<= 8;
m_dwBuff[1] |= I2CReadByte(TW101, 0x81);
wVOffset = (m_dwBuff[1]*32+m_wBuff[0]/2)/m_wBuff[0];
/////////////////////////////////////////////////////
m_dwBuff[0]=DisplayGetXclkCnt(m_dwBuff[0]);
fDHTotalF=DisplayGetHVTotal(&wDHTotal,&wDVTotal,&wDVFrac,wDWVSZ,m_dwBuff[0]);
wVibLeft=DisplayVibration(fDHTotalF,wDHTotal, &wDVTotal,wDWVSZ,wDVFrac);
wDHBlk = (wDHTotal - m_wDWHSZ - DISP_DFLT_HSWIDTH)/2;
wDHBlk += DISP_DFLT_HSWIDTH;
m_wBuff[0] = (unsigned long)wVOffset*100 * wDWVSZ/m_wVRes - wDHBlk * 100 / wDHTotal;
#ifdef T100
DisplaySetPrefill(wDWVSZ,wDHTotal,wDVTotal);
#else
DisplaySetPrefill();//m_wBuff[0],wDWVSZ,wVibLeft,wDHTotal);
#endif
DisplaySetTiming(wDHTotal,wDVTotal);
}
#ifdef T100 //Ruby test 2004-08-19
void DisplaySetPrefill( uWORD wDWVSZ, uWORD wDHTotal,uWORD wDVTotal)//(uWORD wVBlk, uWORD wDWVSZ, uWORD wVibLeft, uWORD wDHTotal,uWORD wDVTotal)
{
uWORD wPrefill;
//To get prefill value roughly
wPrefill = 2450 - (unsigned long)m_wVRes*1000 / 2/wDWVSZ;
// wPrefill = 5450 - (unsigned long)m_wVRes*1000 / 2/wDWVSZ;
//ROUNDUP(x,2)
if(wPrefill%10 > 4)
wPrefill=wPrefill/10+1;
else
wPrefill=wPrefill/10;
//Prefill fraction
wPrefill = wPrefill/100*100+wPrefill%100;
wPrefill = wPrefill +(unsigned long)(wPrefill%100)*m_wHRes/wDHTotal; //Ruby
m_dwBuff[0] = I2CReadByte(TW101, 0x59);
m_dwBuff[0] <<= 8;
m_dwBuff[0] += I2CReadByte(TW101, 0x58);
wPrefill = m_dwBuff[0] * wPrefill /32 / 100;
if(!m_cStandard)
{
m_dwTemp[0]=(wDVTotal-m_wVRes-DWVSST-DISP_DFLT_VSWIDTH)*wDHTotal;
m_dwTemp[1]=wPrefill/DNDIV_40;
if(m_dwTemp[0]<m_dwTemp[1])
I2CWriteByte(TW101, 0x70, I2CReadByte(TW101, 0x70)|0x20);
else
I2CWriteByte(TW101, 0x70, I2CReadByte(TW101, 0x70)&0xDF);
wPrefill-=0x800;
}
else
{
I2CWriteByte(TW101, 0x70, I2CReadByte(TW101, 0x70)|0x20);
#ifndef CPT_7
wPrefill+=0x400;
if(m_cScaleratio==ScaleFULL)wPrefill+=0x200;
#endif
}
I2CWriteByte(TW101, 0x84, (unsigned char)wPrefill);
I2CWriteByte(TW101, 0x85, (unsigned char)(wPrefill>>8));
}
#else
void DisplaySetPrefill(void)//uWORD wVBlk, uWORD wDWVSZ, uWORD wVibLeft, uWORD wDHTotal)
{
uWORD wPrefill;
#ifdef WVGA
if(m_cStandard)
wPrefill = 0x1000+(288-m_wVRes)*0x200/5;
else
wPrefill = 0x100+(240-m_wVRes)*0x300/5;
#endif
#ifdef WXGA
if(m_cStandard)
{
wPrefill = 0x4000+(288-m_wVRes)*0x200/5+DELAY_LINES*0x400;
}
else
{
wPrefill = 0x3800+(240-m_wVRes)*0x300/5+DELAY_LINES*0x400;
}
#endif
/*
#ifdef WXGA
if(m_cStandard)
wPrefill=0x4949;
else
wPrefill=0x3949;
#endif
*/
I2CWriteByte(TW101, 0x70, I2CReadByte(TW101, 0x70)|0x20);
I2CWriteByte(TW101, 0x84, (unsigned char)wPrefill);
I2CWriteByte(TW101, 0x85, (unsigned char)(wPrefill>>8));
}
#endif
extern uCHAR cPAL_OFFSET,cNTSC_OFFSET;
extern uCHAR cPAL_Dot,cNTSC_Dot;
void DisplaySetTiming(uWORD wDHTotal, uWORD wDVTotal)
{
uWORD wTemp;
if(wDHTotal>2400 || wDHTotal<600) return; //unreasonable result
wTemp = ((wDHTotal - m_wDWHSZ - DISP_DFLT_HSWIDTH)>>1)-2;
I2CWriteByte(TW101, 0xB0, wTemp);
I2CWriteByte(TW101, 0xB1, wTemp>>8);
I2CWriteByte(TW101, 0xB2,cPAL_OFFSET ); //DWVSST
#ifdef KVGA
if(!m_cStandard)//NTSC
I2CWriteByte(TW101, 0xB2, cNTSC_OFFSET);
#ifdef LG_7
I2CWriteByte(TW101, 0xB2, cNTSC_OFFSET);
#endif
#endif
#ifdef WVGA
//Ruby test 2004-06-03
if(!m_cStandard)//NTSC
I2CWriteByte(TW101, 0xB2, DWVSST);
else //PAL
I2CWriteByte(TW101, 0xB2, DWVSST-2);
/////
#endif
I2CWriteByte(TW101, 0xB3, 0);
I2CWriteByte(TW101,0xB4,(uCHAR)(m_wDWHSZ)); //4:3
I2CWriteByte(TW101,0xB5,(uCHAR)(m_wDWHSZ>>8));
// if(!m_cStandard)I2CWriteByte(TW101, 0xB8, (unsigned char) (wDHTotal-cNTSC_Dot));
// else
I2CWriteByte(TW101, 0xB8, (unsigned char) (wDHTotal));
I2CWriteByte(TW101, 0xB9, (unsigned char)(wDHTotal>>8));
I2CWriteByte(TW101, 0xBA, (unsigned char) wDVTotal);
I2CWriteByte(TW101, 0xBB, (unsigned char)(wDVTotal>>8));
I2CWriteByte(TW101, 0xBC, (unsigned char) DISP_DFLT_HSWIDTH);
I2CWriteByte(TW101, 0xBD, (unsigned char)(DISP_DFLT_HSWIDTH>>8));
I2CWriteByte(TW101, 0xBE, (unsigned char) DISP_DFLT_VSWIDTH);
I2CWriteByte(TW101, 0xBF, (unsigned char)(DISP_DFLT_VSWIDTH>>8));
}
float DisplayGetHVTotal(uWORD *wDHTotal, uWORD *wDVTotal, uWORD *wDVFrac, uWORD wDWVSZ, uDWORD dwFrameXclkCnt)
{
float fDHTotalF;
//Ruby fDHTotalF = (float)dwFrameXclkCnt * m_wVRes *2/ m_wVTotal / wDWVSZ;
fDHTotalF = (float)dwFrameXclkCnt * m_wVRes/ m_wVTotal / wDWVSZ;
*wDHTotal = (int)fDHTotalF/2 * 2;
#ifdef KVGA
/*
if(!m_cStandard)//NTSC
*wDHTotal = ((int)fDHTotalF/2 * 2);
else
*wDHTotal = ((int)fDHTotalF/2 * 2);
*/
/////
if(!m_cStandard)//NTSC
*wDHTotal = (int)0x0266; //0x0266 for LG_7 0x0265 for AU_7 //0x025E; v36 //0x026B; V34
else
*wDHTotal = (int)0x02EC; //0x02E7; v36 //0x02F1; V34
#endif
#ifdef WVGA
if(!m_cStandard)//NTSC
*wDHTotal = ((int)fDHTotalF/2 * 2);
else
*wDHTotal = ((int)fDHTotalF/2 * 2)-0x0a;
#endif
m_dwBuff[1] = dwFrameXclkCnt*1000/ (*wDHTotal);
*wDVTotal = m_dwBuff[1] / 1000;
*wDVFrac = m_dwBuff[1] % 1000;
return fDHTotalF;
}
uWORD DisplayVibration(float fDHTotalF, uWORD wDHTotal, uWORD* wDVTotal, uWORD wDWVSZ, uWORD wDVFrac)
{
uWORD wActiveDiff;
uWORD wVibLeft;
wActiveDiff=(fDHTotalF-wDHTotal)*wDWVSZ;
if(wDVFrac % 10 >= 5)
wDVFrac = wDVFrac / 10 + 1;
else
wDVFrac = wDVFrac / 10;
if(wDVFrac < 95)
{
wDVFrac = wDVFrac + 5;
m_wBuff[0] = (unsigned long)wDVFrac*wDHTotal/100;
}
else
{
m_wBuff[0] = 0;
}
//m_wBuff[0] is fraction part of output hsync(pixels)
if(m_wBuff[0]<wActiveDiff)
{
if(wActiveDiff-m_wBuff[0]>=wDHTotal*0.3)
{
*wDVTotal -= 1;
m_wBuff[0] += wDHTotal;
}
}
if(m_wBuff[0]>=wActiveDiff)
{
if(wActiveDiff <= (unsigned long)wDWVSZ * 255 / 128)
m_cBuff[0]=(unsigned long)wActiveDiff*128/wDWVSZ;
else
m_cBuff[0]=255;
#ifndef T100 //Ruby test 2004-08-19
I2CWriteByte(TW101, 0x86, m_cBuff[0]);
#endif
//Ruby test 2004-06-03
m_cBuff[0]=(m_wBuff[0]-wActiveDiff)/(*wDVTotal-DWVSST-DISP_DFLT_VSWIDTH-wDWVSZ);
/////
#ifndef T100
I2CWriteByte(TW101, 0x87, m_cBuff[0]);
#endif
wVibLeft=0;
}
else
{
if(m_wBuff[0] <= (unsigned long)wDWVSZ*255/128)
m_cBuff[0]=(unsigned long)m_wBuff[0]*128/wDWVSZ;
else
m_cBuff[0]=255;
#ifndef T100 //Ruby test 2004-08-19
I2CWriteByte(TW101, 0x86, m_cBuff[0]);
I2CWriteByte(TW101, 0x87, 0);
#endif
wVibLeft=(wActiveDiff-m_wBuff[0]);
}
return wVibLeft; //Remap DCLK
}
uDWORD DisplayGetXclkCnt(uDWORD dwFrameXclkCnt)
{
dwFrameXclkCnt *= DNDIV_40;
return dwFrameXclkCnt;
}
uDWORD GetInputVSyncXclkCnt(void)
{
uDWORD dwVSyncCount;
m_cBuff[0] = I2CReadByte(TW101, 0x50);
I2CWriteByte(TW101, 0x50, m_cBuff[0] | 0x10); //Start to Measurement VSYNC counter using XCLK
m_cBuff[0] = 100;
while(m_cBuff[0]--)
{
twdDelay(1);
if ((I2CReadByte(TW101, 0x50)&0x20)) //V sync counter is done exit
break;
}
m_cBuff[0] = I2CReadByte(TW101, 0x50);
m_cBuff[0] &= 0xCF; //Disable Auto Position
I2CWriteByte(TW101, 0x50, m_cBuff[0]);
dwVSyncCount = I2CReadByte(TW101, 0x53);
dwVSyncCount <<= 8;
dwVSyncCount |= I2CReadByte(TW101, 0x52);
dwVSyncCount <<= 8;
dwVSyncCount |= I2CReadByte(TW101, 0x51);
return dwVSyncCount;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -