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

📄 modectrl.c

📁 terawin的t103 LCD驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
				m_dwBuff[0] = m_dwBuff[1];
				EepPrivate.cAltID    = m_cBuff[0];
			}
			}
		}
	}	
        
	if (EepPrivate.cAltID == 0xff)
		return FALSE;
	else 
		return TRUE;
}


void SetModeCaptureData(uWORD wHTotal, uWORD wHsst, uCHAR cVsst, uCHAR cVCO)
{
	//~ Set PLL Freq. ~//	
	I2CWriteByte(TW803_P0, ADC_PLLDIV_H, (cVCO&0x01)<<6);
	//~ Set PLL Divider 0x16[3~0],0x15[7~0] ~//
	I2CWriteByte(TW803_P0, ADC_PLLDIV_H, ((I2CReadByte(TW803_P0, ADC_PLLDIV_H)&0xF0)|((uCHAR)(wHTotal>> 8))));
  	I2CWriteByte(TW803_P0, ADC_PLLDIV_L, (uCHAR)(wHTotal));  
	//~ Set VCO and Charge Pump ~//      
	I2CWriteByte(TW803_P0, ADC_VCOCP, cVCO&0xFE);	
	//~ Set ADC Capture HSync Back Proch 0x4C, 0x4D ~//
  	I2CWriteByte(TW803_P0, HSST_L, (uCHAR)wHsst);
  	I2CWriteByte(TW803_P0, HSST_H, (uCHAR)(wHsst>>8));

  	//~ Set ADC Capture VSync Back Proch 0x4E, 0x4F ~//
	I2CWriteByte(TW803_P0, VSST_L, (uCHAR)cVsst);
	I2CWriteByte(TW803_P0, VSST_H, (uCHAR)(cVsst >> 8));

	//~ Set ADC Capture HSize 0x48, 0x49 ~//
  	I2CWriteByte(TW803_P0, HATVC_L, (uCHAR)m_pResolutionPtr->wHRes);
  	I2CWriteByte(TW803_P0, HATVC_H, (uCHAR)(m_pResolutionPtr->wHRes>>8));
	//~ Set ADC Capture VSize 0x4A, 0x4B ~//
  	I2CWriteByte(TW803_P0, VATVR_L, (uCHAR)m_pResolutionPtr->wVRes);
  	I2CWriteByte(TW803_P0, VATVR_H, (uCHAR)(m_pResolutionPtr->wVRes>>8));
} 


void GetModeCaptureData(void)
{
	if(m_bAlt)
	{
		m_pAltHTotalPtr = &AltHTotals[EepPrivate.cAltID];
		m_cBuff[0] = m_pAltHTotalPtr->cResID;
		m_pResolutionPtr = &ResolutionTable[m_cBuff[0]];
		EepPrivate.wHTotal = m_pAltHTotalPtr->wHTotal;
		m_wHRes = m_pResolutionPtr->wHRes;
		m_wVRes = m_pResolutionPtr->wVRes;
		m_cBuff[0] = m_pAltHTotalPtr->cModeFlags;  //VCO & Charge Pump
	}
	else
	{
		m_pModeDescriptorPtr = &ModeTable[EepPrivate.cModeID];
		
		m_cBuff[0] = m_pModeDescriptorPtr->cResID;
		m_pResolutionPtr = &ResolutionTable[m_cBuff[0]];
		EepPrivate.wHTotal = m_pModeDescriptorPtr->wHTotal;
		m_wHRes = m_pResolutionPtr->wHRes;
		m_wVRes = m_pResolutionPtr->wVRes;
		m_cBuff[0] = m_pModeDescriptorPtr->cModeFlags2; //VCO & Charge Pump
	}
/*  Ruby 2005 11 01
	if (m_cModeStatus & ADCHIGHRANGE)
	{
		EepPrivate.wHTotal /= 2;
		m_wHRes /= 2;	
	}

	if (m_cModeStatus & ADCLOWRANGE)
	{
		EepPrivate.wHTotal *= 2;
		m_wHRes *= 2;	
	}	
*/
	if(m_bInterlaced)
	{
		m_wVRes /= 2;
	}

	
}

//Only used in analog inputs
void SetupMode(void)
{ 
   if(!m_bDigital)
	{                        
		if(I2CReadByte(TW803_P0, 0x3F)&0x10)
			I2CWriteByte(TW803_P0, 0x63, 0xCF);
		else
			I2CWriteByte(TW803_P0, 0x63, 0x40);	
	}
   
	GetModeCaptureData();
	//m_cBuff[0] saved VCO&Charge Pump
	SetModeCaptureData(EepPrivate.wHTotal, FIXEDHSST, FIXEDVSST, m_cBuff[0]);

}


#define MINVRES		0x0000
#define MAXVRES		0xFFFF
BOOL GetVResolution(void)
{
	//How to define THRESHOLD is a question mark, need confirm later. 
	McWaitReady(0x04, 0x08);

	//start data
	m_wBuff[0] = I2CReadByte(TW803_P0, POS_TB_H);        
	m_wBuff[0] <<= 8;
	m_wBuff[0] |= I2CReadByte(TW803_P0, POS_TB_L); 
	
	//end data
	m_wBuff[1] = I2CReadByte(TW803_P0, POS_BB_H);       
	m_wBuff[1] <<= 8;
	m_wBuff[1] |= I2CReadByte(TW803_P0, POS_BB_L);

	m_wVRes = m_wBuff[1] - m_wBuff[0] + 1;
     	
	
	return FALSE;

	//How can I know the VRes is valid or not, inputs depend on input pattern 
	if (m_wVRes >= MINVRES && m_wVRes <= MAXVRES)
		return TRUE;
	else
		return FALSE;
}	   



void GetModeInfo(uWORD *wVTotal, uWORD *wHPeriodCount, uDWORD dwFrameCnt)
{	
	uWORD	wTemp;
	int i;
	
	//~ Get HSync period. ~//
	I2CWriteByte(TW803_P0, 0x14, I2CReadByte(TW803_P0, 0x14)&0xEF);	// Disable HSo source from PLL.
	I2CWriteByte(TW803_P0, 0x16, I2CReadByte(TW803_P0, 0x16)|0x04);	// Set PLL divider default value.
	wTemp=0;
	for(i=0; i<30; i++)
	{
		twdDelay1(10);	
		*wHPeriodCount = I2CReadByte(TW803_P0, HS_PERIOD_H);
		*wHPeriodCount <<= 8;
		*wHPeriodCount += I2CReadByte(TW803_P0, HS_PERIOD_L);
		if((wTemp&0xFF00)==((*wHPeriodCount)&0xFF00))
			break;
		else
			wTemp = *wHPeriodCount;
	}
	wTemp = dwFrameCnt * 32 * 10 / (*wHPeriodCount); 
	if(wTemp % 10 >= 9)
		m_wBuff[0] = wTemp/10 + 1;
	else	
		m_wBuff[0] = wTemp/10;
	
	*wVTotal = m_wBuff[0]; 
	I2CWriteByte(TW803_P0, 0x14, I2CReadByte(TW803_P0, 0x14)|(~0xEF)); 	// Enable HSo source from PLL.
}



	  
// ================================================================
//	McPolDetect			Kevin Hsu.	Mar. 2th, 2006
// ================================================================
//	Description: Detect VSyn and HSyn polarity. 
//	Output:		 VGA sync. type.
//	---------------------------------------------------------------
uCHAR McPolDetect(void)
{
	I2CWriteByte(TW803_P0, 0x10, I2CReadByte(TW803_P0, 0x10)|0x10);
	m_cBuff[0] = I2CReadByte(TW803_P0, 0x10)>>6; 
	return m_cBuff[0]&0x03;
}

BOOL McWaitReady(uCHAR cEnableBit, uCHAR cReadyBit)
{
	I2CWriteByte(TW803_P0, 0x50, I2CReadByte(TW803_P0, 0x50)|cEnableBit);
	
	m_cBuff[0] = 0xFF;
	while(m_cBuff[0]--)
	{ 
		twdDelay(1);
		if(I2CReadByte(TW803_P0, 0x50)&cReadyBit)
			break;
	}
	//Disable Enable bit for next sync coming in
	I2CWriteByte(TW803_P0, 0x50, I2CReadByte(TW803_P0, 0x50)&~(cEnableBit|cReadyBit));
	if(m_cBuff[0])	return TRUE;
	else return FALSE; 
}


// ================================================================
//	GetInputVSyncXclkCnt			Kevin Hsu.	Mar. 7th, 2006
// ================================================================
//	Description: Get VSync. period  
//	Output:		 dwVSyncCount : VSync period.
//	---------------------------------------------------------------
uDWORD GetInputVSyncXclkCnt(void)			 
{
	uDWORD dwVSyncCount;

	I2CWriteByte(TW803_P0, 0x14, I2CReadByte(TW803_P0, 0x14)&0xEF);	// Disable HSo source from PLL.
	
	m_dwBuff[0] = 0;
	m_cBuff[1]=20;
RECHECK:		
	twdDelay(100);		
	m_cBuff[1]--;
	m_cBuff[0] = I2CReadByte(TW803_P0, 0x50);
	I2CWriteByte(TW803_P0, 0x50, m_cBuff[0] | 0x10);    	//Enable VSYNC counter
	m_cBuff[0] = 100;
	while(m_cBuff[0]--)
	{
		twdDelay(1);
		if ((I2CReadByte(TW803_P0, 0x50)&0x20)) //V sync counter is done exit
			break;
	}	   
	m_cBuff[0] = I2CReadByte(TW803_P0, 0x50);
	m_cBuff[0] &= 0xCF;			//Disable Auto Position
	I2CWriteByte(TW803_P0, 0x50, m_cBuff[0]);

	dwVSyncCount =  I2CReadByte(TW803_P0, 0x53);
	dwVSyncCount <<= 8;
	dwVSyncCount |= I2CReadByte(TW803_P0, 0x52);
	dwVSyncCount <<= 8;
	dwVSyncCount |= I2CReadByte(TW803_P0, 0x51);
	if((m_dwBuff[0]&0xFFFF00)!=(dwVSyncCount&0xFFFF00))
	{
		m_dwBuff[0] = dwVSyncCount;
		if(m_cBuff[1])
			goto RECHECK;
	}
	I2CWriteByte(TW803_P0, 0x14, I2CReadByte(TW803_P0, 0x14)|(~0xEF)); 	// Enable HSo source from PLL.
	return dwVSyncCount;	
}
void VGAScaling(void)
{
	float x;
 	m_wBuff[0] = I2CReadByte(TW803_P0, 0x59);
	m_wBuff[0] <<= 8;
	m_wBuff[0] |= I2CReadByte(TW803_P0, 0x58);	

	switch(m_cDspPllSwitch)
	{
		case DSPPLL_100:x=DNDIV_100;break;
		case DSPPLL_108:x=DNDIV_108;break;
		case DSPPLL_120:x=DNDIV_120;break;
		case DSPPLL_136:x=DNDIV_136;break;
		case DSPPLL_140:x=DNDIV_140;break;
		default:x=DNDIV_108;break;
	}

	if((float)EepPrivate.wHTotal*32/ m_wBuff[0]>x)
		I2CWriteByte(TW803_P0, 0x70, I2CReadByte(TW803_P0, 0x70)|DCLKI_IS_FASTER);	//Input clk faster, enable this bit
	else
		I2CWriteByte(TW803_P0, 0x70, I2CReadByte(TW803_P0,0x70)&~DCLKI_IS_FASTER);	//Input clk slower, disable this bit
 
	//Horizontal	
	m_wBuff[0] = (float)m_wHRes/VGAState.HDispSize * 0x2000; 
	I2CWriteByte(TW803_P0, SC_HOR_H1, (uCHAR)m_wBuff[0]);
    I2CWriteByte(TW803_P0, SC_HOR_H2, (uCHAR)(m_wBuff[0]>>8));

	//Vertical
	if(!(m_cModeStatus & VSYNCOVERRANGE))
	{
		m_wBuff[0] = (float)m_wVRes/(VGAState.VDispSize) * 0x2000;
	}
	else
	{
		m_wBuff[0] = (float)m_wVRes/(VGAState.VDispSize) * 0x2000;  
	}

	I2CWriteByte(TW803_P0, SC_VER_V1, (uCHAR)m_wBuff[0]);
	I2CWriteByte(TW803_P0, SC_VER_V2, (uCHAR)(m_wBuff[0]>>8)); 
	I2CWriteByte(TW803_P0, 0xDC, (uCHAR)VGAState.HDispSize);
	I2CWriteByte(TW803_P0, 0xDD, (uCHAR)(VGAState.HDispSize>>8));
	I2CWriteByte(TW803_P0, 0xDE, (uCHAR)VGAState.VDispSize);
	I2CWriteByte(TW803_P0, 0xDF, (uCHAR)(VGAState.VDispSize>>8));
}

void VGASetPll(void)
{								
	switch(m_pModeDescriptorPtr->cModeFlags0 & DSPPLL_MASK)
	{
		case bDSPPLL_100:m_cDspPllSwitch=DSPPLL_100;break;
		case bDSPPLL_108:m_cDspPllSwitch=DSPPLL_108;break;
		case bDSPPLL_120:m_cDspPllSwitch=DSPPLL_120;break;
		case bDSPPLL_136:m_cDspPllSwitch=DSPPLL_136;break;
		case bDSPPLL_140:m_cDspPllSwitch=DSPPLL_140;break;
		default:m_cDspPllSwitch=DSPPLL_108;break;
	}
	switch(m_cDspPllSwitch)
	{
		case DSPPLL_100:I2CWriteByte(TW803_P0, PLLDIV_F,DFDIV_100);break;
		case DSPPLL_108:I2CWriteByte(TW803_P0, PLLDIV_F,DFDIV_108);break;
		case DSPPLL_120:I2CWriteByte(TW803_P0, PLLDIV_F,DFDIV_120);break;
		case DSPPLL_136:I2CWriteByte(TW803_P0, PLLDIV_F,DFDIV_136);break;
		case DSPPLL_140:I2CWriteByte(TW803_P0, PLLDIV_F,DFDIV_140);break;  
		default:	I2CWriteByte(TW803_P0, PLLDIV_F,DFDIV_108);break;
	}  						   
	I2CWriteByte(TW803_P0, PLLDIV_I,DIDIV);
	I2CWriteByte(TW803_P0, PLLDIV_O,0x10|DODIV); 
 /*	m_cDspPllSwitch=DSPPLL_140;
	I2CWriteByte(TW803_P0, PLLDIV_F,DFDIV_140);
	I2CWriteByte(TW803_P0, PLLDIV_I,DIDIV);
	I2CWriteByte(TW803_P0, PLLDIV_O,0x10|DODIV);	 */
}												  



// ================================================================
//	VGACalOPTiming							Kevin Hsu.	Mar. 15th, 2006
// ================================================================
//	Description: Calculate output timming.  
//	Output:		 None.
//	--------------------------------------------------------------- 
#define LB_WIDTH 1280	// For T103											   
void VGACalOPTiming(void)
{
	uWORD wDVTotal, wDHTotal, wDVBILK, wTemp;
	float Temp, DNDIV_40_Temp;

	//~ Calculate PH_TOT and PV_TOT ~//
	m_wBuff[0] = I2CReadByte(TW803_P0, 0x59);
	m_wBuff[0] <<= 8;
	m_wBuff[0] |= I2CReadByte(TW803_P0, 0x58);	
	m_wBuff[0] /= 32;	
	m_dwBuff[0] = I2CReadByte(TW803_P0, 0x53);
	m_dwBuff[0] <<= 8;
	m_dwBuff[0] |= I2CReadByte(TW803_P0, 0x52);					 	
	m_dwBuff[0] <<= 8;
	m_dwBuff[0] |= I2CReadByte(TW803_P0, 0x51);
	DNDIV_40_Temp = ((float)(I2CReadByte(TW803_P0, PLLDIV_F)+2)/(DIDIV+2)/DRDIV);
	Temp = (27000000.0/m_dwBuff[0])*m_pModeDescriptorPtr->wHTotal*m_pModeDescriptorPtr->wVTotal;
	if(Temp>(DNDIV_40_Temp*27000000.0))
		I2CWriteByte(TW803_P0, 0x70, I2CReadByte(TW803_P0, 0x70)|0x20);
	else
		I2CWriteByte(TW803_P0, 0x70, I2CReadByte(TW803_P0, 0x70)&0xDF);	
	wDHTotal=(float)m_wBuff[0]*m_wVRes*DNDIV_40_Temp/VGAState.VDispSize;		   	
	wDVTotal=((DNDIV_40_Temp*(float)XCLK)/(float)(((float)(XCLK)/m_pModeDescriptorPtr->dwVFrameCount)*wDHTotal));

	twdDelay(100);
	m_dwBuff[1]=I2CReadByte(TW803_P0, 0x83);
	m_dwBuff[1] <<= 8;
	m_dwBuff[1]=I2CReadByte(TW803_P0, 0x82);
	m_dwBuff[1] <<= 8;
  	m_dwBuff[1] |= I2CReadByte(TW803_P0, 0x81);
	wDVBILK=m_dwBuff[1];
	
	//~ Calculate back porch "DWHS" ~//
	wTemp = ((wDHTotal - DWHSZ - DISP_DFLT_HSWIDTH)>>1); 

	I2CWriteByte(TW803_P0, 0xB0, wTemp);
	I2CWriteByte(TW803_P0, 0xB1, wTemp>>8);//Horizontal back porch	
	I2CWriteByte(TW803_P0, 0xB2, DISP_DFLT_VDS);
	I2CWriteByte(TW803_P0, 0xB3, DISP_DFLT_VDS>>8);//Vertical back porch 
	I2CWriteByte(TW803_P0, 0xB4,(uCHAR)(DWHSZ));	
	I2CWriteByte(TW803_P0, 0xB5,(uCHAR)(DWHSZ>>8));//Horizontal width
	I2CWriteByte(TW803_P0, 0xB6,(uCHAR)(DWVSZ));	
	I2CWriteByte(TW803_P0, 0xB7,(uCHAR)(DWVSZ>>8));//Vertical height
	I2CWriteByte(TW803_P0, 0xB8,(uCHAR) wDHTotal);
	I2CWriteByte(TW803_P0, 0xB9,(uCHAR)(wDHTotal>>8));//Htotal
	I2CWriteByte(TW803_P0, 0xBA,(uCHAR) wDVTotal);
	I2CWriteByte(TW803_P0, 0xBB,(uCHAR)(wDVTotal>>8));//Vtotal	              
	I2CWriteByte(TW803_P0, 0xBC,(uCHAR) DISP_DFLT_HSWIDTH);
	I2CWriteByte(TW803_P0, 0xBD,(uCHAR)(DISP_DFLT_HSWIDTH>>8));//HSYNC Width	
	I2CWriteByte(TW803_P0, 0xBE,(uCHAR) DISP_DFLT_VSWIDTH);
	I2CWriteByte(TW803_P0, 0xBF,(uCHAR)(DISP_DFLT_VSWIDTH>>8));//VSYNC Width	 
			 
	//~ Calculate line buffer ~//
	if(H_Size>m_wHRes) 				  // HSize in LB
		m_wBuff[1] = m_wHRes; 
	else
		m_wBuff[1] = H_Size; 
	
	if(LB_WIDTH >= (m_wBuff[1]<<1))	  //PREFILL Size
		Temp = 4.0;					
	else
	{
		Temp = 2.45 - ((float)(m_wVRes)/V_Size)/2.0;
	 	if(LB_WIDTH>=m_wBuff[1])
			Temp += (LB_WIDTH-m_wBuff[1])/m_wBuff[1];
		else
			Temp += 0;
	}		 
	m_wBuff[1] = ((Temp-(int)(Temp))*m_wHRes/EepPrivate.wHTotal + (int)(Temp))*m_wBuff[0]; // T_PerFill
	m_wBuff[2] = ((DISP_DFLT_VSWIDTH+DISP_DFLT_VDS+I2CReadByte(TW803_P0, 0xDA))*wDHTotal + DISP_DFLT_HSWIDTH + wTemp + I2CReadByte(TW803_P0, 0xD8))/DNDIV_40_Temp; //VBo_Xclk
	m_dwBuff[1] =I2CReadByte(TW803_P0, 0x53);
	m_dwBuff[1] <<= 8;
	m_dwBuff[1] |=I2CReadByte(TW803_P0, 0x52);
	m_dwBuff[1] <<= 8;
  	m_dwBuff[1] |= I2CReadByte(TW803_P0, 0x51);
	Temp = ((m_dwBuff[1]+1)*DNDIV_40_Temp * m_wVRes)/((m_dwBuff[1]/m_wBuff[0]) *VGAState.VDispSize);  // Ideal PH_TOT
	m_wBuff[0] =  (Temp - (float)wDHTotal)*VGAState.VDispSize/DNDIV_40_Temp/2;
 	//~ VSDLY_XCLK = T_PreFill + VBi_XClk + (End_LB_Short/2) - VBo_Xclk ~//
	m_dwBuff[0] = m_wBuff[1] + wDVBILK +m_wBuff[0];
	wTemp = m_dwBuff[0]-m_wBuff[2];	 	  
	I2CWriteByte(TW803_P0, 0x84, wTemp);
	I2CWriteByte(TW803_P0, 0x85, wTemp>>8);//line buffer delay XClk

	m_dwBuff[0]=(wDVTotal-m_wVRes-DWVSST-DISP_DFLT_VSWIDTH)*wDHTotal;
	m_dwBuff[1]=wTemp*DNDIV_40_Temp;
	if(m_dwBuff[0]<m_dwBuff[1])
		I2CWriteByte(TW803_P0, 0x70, I2CReadByte(TW803_P0, 0x70)|0x20);
	else
		I2CWriteByte(TW803_P0, 0x70, I2CReadByte(TW803_P0, 0x70)&0xDF);	  
} 	 																	  



BOOL SyncChangDect()
{
	//~ Detect V/H Sync changed. ~//
	if(I2CReadByte(TW803_P0, 0x32)&0x0C)
	{
		ClosePanel(0x10,0xFF,0x40);	  
		if(!SrcAnalogProcess()) 
		{
			I2CWriteByte(TW803_P0, 0x32, 0x0F);	
			return FALSE;
		}
		OpenPanel();
		I2CWriteByte(TW803_P0, 0x32, 0x0C);	
		return TRUE;
	}
	//~ Detect if V/H Sync lost. ~//
	if((I2CReadByte(TW803_P0, 0x32)&0x03)==0x03)
	{
		ClosePanel(0x10,0xFF,0x40);
		I2CWriteByte(TW803_P0, 0x32, 0x0F);
		return FALSE;
	} 
	return TRUE;
	

}

BOOL SrcAnalogProcess(void)
{
	Sync_Mode_Detect();
	if(!ModeDetect()) return FALSE;
	SetupMode();
	VGASetPll(); 	
	AutoPositionAdj(0xF0);
	VGAState.HDispSize = H_Size;
	VGAState.VDispSize = V_Size;
	VGAState.fHDispSize = H_Size;
	VGAState.fVDispSize = V_Size;
	VGAState.AdjHATV = m_wHRes; 
	VGAState.AdjVATV = m_wVRes; 
	VGACalOPTiming();
	VGAScaling(); 
	OpenPanel();
	I2CWriteByte(TW803_P0, INT_STATUS, 0x3f);
	I2CWriteByte(TW803_P0, 0xE2, 0x11);
	AutoPhaseAdj();	
	if(!(m_cModeStatus&(DOSMODE|NORMALMODE))) //(OVERRANGE |SYNCERROR))
	{
	  	return FALSE;
	}

	I2CWriteByte(TW803_P0, INT_STATUS, 0x3f);
	I2CWriteByte(TW803_P0, 0xE2, 0x11);
	VGAState.PositionH = I2CReadByte(TW803_P0, 0x45);
	VGAState.ADCVBaPorch = I2CReadByte(TW803_P0, VSST_L)|(I2CReadByte(TW803_P0, VSST_H)<<8);	
	VGAState.ADCHBaPorch = I2CReadByte(TW803_P0, HSST_L)|(I2CReadByte(TW803_P0, HSST_H)<<8);	
	VGAState.HATV = I2CReadByte(TW803_P0, HATVC_L)|(I2CReadByte(TW803_P0, HATVC_H)<<8);
	VGAState.VATV = I2CReadByte(TW803_P0, VATVR_L)|(I2CReadByte(TW803_P0, VATVR_H)<<8);	 
	return TRUE;
}

#endif









⌨️ 快捷键说明

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