iic.c

来自「台湾联咏NT68663 LCD MONITOR 控制程序(完整版)」· C语言 代码 · 共 434 行

C
434
字号
#include "stdio.h"
#include "8051.H"
#include "RAM.H"
#include "IIC.H"
#include "MCU.H"
#include "ROM_MAP.H"
#include "MyDef.H"
#include "F63XREG.H"
#include "F63XDEF.H"
#include "INTRINS.H"
void DDC2(void)
{
	ISCL = 0;
	ISCL = 1;
}

void IIC_Start(void)
{
	ISDA = 0;
	ISCL = 0;
}

void IIC_Stop(void)
{
	ISDA = 0;
	ISCL = 1;
	ISDA = 1;
}

void CheckIIC(void)
{
	ISCL = 1;
	ISDA = 1;
	while(!ISDA || !ISCL)	//waiting for IIC released
		{
		ISCL = 0;
		IIC_Stop();
		}
}

Byte IIC_Tx(Byte Data)
{	//subroutine total time 630us
	Byte AckLoop,Ack;

#if SOFTWAREIIC_220K == 0
	Byte i;
	for(i=0;i<8;i++)
		{
	    ISCL = 0;
		ISDA = (Data & 0x80);
		_nop_();
		_nop_();
		ISCL = 1;
		_nop_();
		_nop_();
		Data <<= 1;
		}
#else
	ISCL = 0;
	ISDA = (Data & 0x80);
	ISCL = 1;
    ISCL = 0;
	ISDA = (Data & 0x40);
	ISCL = 1;
    ISCL = 0;
	ISDA = (Data & 0x20);
	ISCL = 1;
    ISCL = 0;
	ISDA = (Data & 0x10);
	ISCL = 1;
    ISCL = 0;
	ISDA = (Data & 0x08);
	ISCL = 1;
    ISCL = 0;
	ISDA = (Data & 0x04);
	ISCL = 1;
    ISCL = 0;
	ISDA = (Data & 0x02);
	ISCL = 1;
    ISCL = 0;
	ISDA = (Data & 0x01);
	ISCL = 1;
#endif
	//
	ISCL = 0;
	ISDA = 1;
	ISCL = 1;
	Ack = NACK;
	for(AckLoop=0;AckLoop<20;AckLoop++) //260us
		{
		if(!ISDA)
			{
			Ack = ACK;
			break;
			}
		}
	ISCL = 0;
	return Ack;			//return success=0 / failure=1
}
/*
Byte IIC_TxV(Byte Data)
{	//subroutine total time 630us
	Byte AckLoop,Ack;
	Byte i;
	for(i=0;i<8;i++)
		{
	    ISCL = 0;
		if(i == 7)
			WaitVblank();
		ISDA = (Data & 0x80);
		ISCL = 1;
		Data <<= 1;
		}
	ISCL = 0;
	ISDA = 1;
	ISCL = 1;
	Ack = NACK;
	for(AckLoop=0;AckLoop<20;AckLoop++) //260us
		{
		if(!ISDA)
			{
			Ack = ACK;
			break;
			}
		}
	ISCL = 0;
	return Ack;			//return success=0 / failure=1
}
*/
Byte IIC_Rx(Bit Ack)
{
	Byte Data;
	Byte i;
	Data = 0;
	for(i=0;i<8;i++)
		{
		Data <<= 1;
		ISCL = 0;
		ISDA = 1;
		ISCL = 1;
		if(ISDA)
			Data |= 1;
		else
			Data &= 0xfe;
		}
	ISCL = 0;
	ISDA = Ack;
	ISCL = 1;
	ISCL = 0;
	return Data;
}

void WaitEEprom(void)
{
	Byte i,ack;
	for(i=0;i<100;i++)  //10ms 
		{
		IIC_Start();
		ack = IIC_Tx(0xa0);	//polling ACKnowledge
		IIC_Stop();
		if(ack == ACK)
			break;
		CLRWDT = 0x55;
		}
}

void WriteIIC(Byte device,Byte addr,Byte ch)
{
	IIC_Start();
	IIC_Tx(device);
	IIC_Tx(addr);
	IIC_Tx(ch);
	IIC_Stop();
}
/*
void WriteWordIIC(unsigned char device,unsigned char addr,unsigned short value)
{
	IIC_Start();
	IIC_Tx(device);
	IIC_Tx(addr);
	IIC_Tx((Byte)value);
	IIC_Tx((Byte)(value>>8));
	IIC_Stop();
}
*/
void WriteIIC563(unsigned short addr,unsigned char ch)
{
	CheckRegPage(addr);
	IIC_Start();
	IIC_Tx(SCALER_ADDR);
	IIC_Tx(addr);
	IIC_Tx(ch);
	IIC_Stop();
}

void WriteWordIIC563(unsigned short addr,unsigned short value)
{
	CheckRegPage(addr);
	IIC_Start();
	IIC_Tx(SCALER_ADDR);
	IIC_Tx((Byte)addr);
	IIC_Tx((Byte)value);
	IIC_Tx((Byte)(value>>8));
	IIC_Stop();
}

Byte ReadIIC(Byte device,Byte addr)
{
	Byte value;
	IIC_Start();
	IIC_Tx(device);
	IIC_Tx(addr);
	ISDA = 1;	//repeat start
	ISCL = 1;
	ISDA = 0;
	ISCL = 0;
	IIC_Tx(device+1);
	value = IIC_Rx(NACK);	//nack
	IIC_Stop();
	return value;
}

unsigned char ReadIIC563(unsigned short addr)
{
	Byte value;
	CheckRegPage(addr);
	IIC_Start();
	IIC_Tx(SCALER_ADDR);
	IIC_Tx(addr);
	ISDA = 1;	//repeat start
	ISCL = 1;
	ISDA = 0;
	ISCL = 0;
	IIC_Tx(SCALER_ADDR+1);
	value = IIC_Rx(NACK);	//nack
	IIC_Stop();
	return value;
}

unsigned short ReadWordIIC563(unsigned short addr)
{
	Byte temp;
	Word value;
	CheckRegPage(addr);
	IIC_Start();
	IIC_Tx(SCALER_ADDR);
	IIC_Tx(addr);
	ISDA = 1;	//repeat start
	ISCL = 1;
	ISDA = 0;
	ISCL = 0;
	IIC_Tx(SCALER_ADDR+1);
	temp = IIC_Rx(ACK);
	value = IIC_Rx(NACK);	//nack
	value <<= 8;
	value += temp;
	IIC_Stop();
	return value;
}
unsigned char Read24C16(unsigned short addr16)
{
	Byte ch;
	Byte device,addr;
	addr = addr16 & 0x0ff;
	device = (addr16 >> 7) & 0x0e;
	device |= EEPROM;
	ch = ReadIIC(device,addr);
	return ch;
}

void CheckRegPage(unsigned short addr)
{
	Byte page;
	IIC_Start();
	IIC_Stop();
	page = (Byte)((addr/256) & 0x003);
	if(page != RegPage)
		{
		RegPage = page;
		WriteIIC(SCALER_ADDR,0xff,RegPage);
		}
}

void InitEEPROM(void)
{
	unsigned short addr;
	#if PRINT_MESSAGE
		printf("Initial EEPROM.\n");
	#endif
	LED_GrnOff();
	LED_RedOn();
	//Dsub EDID
	for(addr=0;addr<0x80;addr++)
		Write24C16(ep_DDC_Analog+addr,DsubEdidTab[addr]);
	//Dvi EDID
	for(addr=0;addr<0x80;addr++)
		Write24C16(ep_DDC_DVI+addr,DviEdidTab[addr]);
	//Geo
	LED_RedOff();
	for(addr=0;addr<0x45;addr++)
		Write24C16(0x200+addr,EEP_GeoMap[addr]);
	//Mode
	LED_RedOn();
	for(addr=0;addr<UserModeSt*4;addr++)
		Write24C16(0x300+addr,EEP_FreqMap[addr]);
	LED_RedOff();
	for(;addr<ModeNum*4;addr++)
		Write24C16(0x300+addr,0xff);
	//Sync
	LED_RedOn();
	for(addr=0;addr<UserModeSt*8;addr++)
		Write24C16(0x500+addr,EEP_SyncMap[addr]);
	LED_RedOff();
	for(;addr<ModeNum*8;addr++)
		Write24C16(0x500+addr,0xff);
	Write24C16(ep_FirmWare_Ver,Version);
	Write24C16(ep_FirmWare_Rev,Reversion);
	LED_GrnOn();
}

void Write24C16(unsigned short k,unsigned char ch)
{
unsigned char device,addr;
	addr = (unsigned char)k;
	device = (unsigned char)((k>>7)&0x0e);
	device |= EEPROM;
	WriteIIC(device,addr,ch);
	WaitEEprom();
}
/*
void WritePage24C16(unsigned short addr1,unsigned short addr2,unsigned char *p)
{
unsigned char i,ch;
	IIC_Start();
	i = (unsigned char)((addr1 >>7 ) & 0x0e);
	i |= EEPROM;
	IIC_Tx(i);
	IIC_Tx((Byte)addr1);
	for(i=0; i<16; i++)
		{
		ch = p[addr2 + i];
		IIC_Tx(ch);
		}
	IIC_Stop();
	WaitEEprom();
}
*/
void LoadDDCData()
{
	Byte xdata *DDCptr;
	Byte i;
	DDC_CTL0 = 0;		//disable DDC
	DDC_CTL1 = 0;		//disable DDC
	DDCptr = 0xf800;  
	for(i=0;i<128;i++)
		{
		CLRWDT = 0x55;
		*DDCptr++ = Read24C16(ep_DDC_DVI+i);
		}
	DDCptr = 0xf900;  
	for(i=0;i<128;i++)
		{
		CLRWDT = 0x55;
		*DDCptr++ = Read24C16(ep_DDC_Analog+i);
		}
	DDC_CTL0 = (EN_DDC|CLR_UPD|CLR_PTR);	
	DDC_CTL1 = (EN_DDC|CLR_UPD|CLR_PTR);	
}

void SaveDDCData(Bit Channel)
{
	Byte xdata *DDCptr;
	Byte i,ptr;
	DDC_CTL0 = 0;		//disable DDC
	DDC_CTL1 = 0;		//disable DDC
	if(Channel == 0)
		{
		DDCptr = 0xf800;
		for(i=0;i<16;i++)
			{
			IIC_Start();
			IIC_Tx(0xa2);
			IIC_Tx(i*8);
			for(ptr=0;ptr<8;ptr++) //page write 8bytes(16bytes max)
				IIC_Tx(*DDCptr++);
			IIC_Stop();
			WaitEEprom();	//polling acknowledge
			CLRWDT = 0x55;
			}
		}
	else
		{
		DDCptr = 0xf900;
		for(i=0;i<16;i++)
			{
			IIC_Start();
			IIC_Tx(0xa0);
			IIC_Tx(i*8);
			for(ptr=0;ptr<8;ptr++) //page write 8bytes(16bytes max)
				IIC_Tx(*DDCptr++);
			IIC_Stop();
			WaitEEprom();	//polling acknowledge
			CLRWDT = 0x55;
			}
		}
	DDC_CTL0 = (EN_DDC|CLR_UPD|CLR_PTR);	
	DDC_CTL1 = (EN_DDC|CLR_UPD|CLR_PTR);	
	if(!Channel)
		SaveDDC0 = 0;
	else
		SaveDDC1 = 0;
}

void CheckVersion()
{
	Byte i,Ver1,Ver2;
	for(i=0;i<10;i++)
		{
		Ver1 = Read24C16(ep_FirmWare_Ver);
		Ver2 = Read24C16(ep_FirmWare_Rev);
		if(Ver1 == Version && Ver2 == Reversion)
			break;
		Sleep(10);
		}
	if(i==10)
		{
		#if PRINT_MESSAGE
			printf("Version error.\n");
		#endif
		InitEEPROM();
		}
}

⌨️ 快捷键说明

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