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

📄 display.c

📁 TFT LCD驱动芯片T100A+AU7" Source code
💻 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 + -