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

📄 i2c.cpp

📁 混泰CH7023,CH7024,CH7025视频解码芯片
💻 CPP
字号:
#include "precomp.h"
#include "I2C.h"

void I2C::InitializeGPIO()
{
	//config GPIO as I2C port:
	s2410IOP->rGPECON &= 0x0FFFFFFF;
	s2410IOP->rGPECON |= 0xA0000000;
	s2410IOP->rGPEUP |= 0xC000;
}

void I2C::ReInitialize()
{
	//config GPIO as output port:
	s2410IOP->rGPECON &= 0x0FFFFFFF;
	s2410IOP->rGPECON |= 0x50000000;
	s2410IOP->rGPEUP |= 0xC000;
	//Ouput pulses:
	for(int i=0;i<100;i++)
	{
		s2410IOP->rGPEDAT &= 0x3FFF;
		s2410IOP->rGPEDAT &= 0x3FFF;
		s2410IOP->rGPEDAT |= 0xC000;
		s2410IOP->rGPEDAT |= 0xC000;
	}
	s2410IOP->rGPEDAT |= 0xC000;
	//Init IIC:
	Initialize();
}

BOOL I2C::InitAddress()
{
	BOOL RetVal=TRUE;
	RETAILMSG(1,(_T("I2C::InitAddress()\r\n")));
	//IO registers:
	s2410IOP=(volatile S3C2410_IOPreg*)VirtualAlloc(0,sizeof(S3C2410_IOPreg),MEM_RESERVE,PAGE_NOACCESS);
	if(s2410IOP==NULL)
	{
		ERRORMSG(1,(_T("VirtualAlloc() failed!\n")));
		RetVal=FALSE;
	}
	else
	{
		RETAILMSG(1,(_T("IOP register:virtual address=0x%.8x\n"),s2410IOP));
		if(!VirtualCopy((PVOID)s2410IOP,(PVOID)(S3C2410_IOP_PA_BASE>>8),sizeof(S3C2410_IOPreg),PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE))
		{
			ERRORMSG(1,(_T("VirtulaCopy() failed!\n")));
			RetVal=FALSE;
		}
	}
	if(!RetVal)
	{
		RETAILMSG(1,(_T("Init IOP Address failed!\n")));
		if(s2410IOP)
			VirtualFree((PVOID)s2410IOP,0,MEM_RELEASE);
		s2410IOP=NULL;
		RetVal=FALSE;
		return RetVal;
	}
	
	//IIC registers:
	s2410IIC=(volatile S3C2410_IICreg*)VirtualAlloc(0,sizeof(S3C2410_IICreg),MEM_RESERVE,PAGE_NOACCESS);
	if(s2410IIC==NULL)
	{
		ERRORMSG(1,(_T("VirtualAllco() failed!\n")));
		RetVal=FALSE;
	}
	else
	{
		RETAILMSG(1,(_T("IIC register:virtual address=0x%.8x\n"),s2410IIC));
		if(!VirtualCopy((PVOID)s2410IIC,(PVOID)(S3C2410_IIC_PA_BASE>>8),sizeof(S3C2410_IICreg),PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE))
		{
			ERRORMSG(1,(_T("VirtualCopy() failed!\\n")));
			RetVal=FALSE;
		}
	}
	if(!RetVal)
	{
		RETAILMSG(1,(_T("Init IIC Address failed!\n")));
		if(s2410IIC)
			VirtualFree((PVOID)s2410IIC,0,MEM_RELEASE);
		s2410IIC=NULL;
		RetVal=FALSE;
	}

	return RetVal;
}

//Initialize IIC controller...
void I2C::Initialize()
{
	//Initialize GPIO for IIC
	InitializeGPIO();
	//ACK enable;IICCLK=FPCLK/512=97656(Hz);Tx/Rx interrupt enable;
	s2410IIC->rIICCON = (1<<7) | (1<<6) | (1<<5) | (m_clkdiv&0x0F); 
	//Master mode; data output enable
	s2410IIC->rIICSTAT = (3<<6) | (1<<4);
	//For as slave mode
	s2410IIC->rIICADD = 0x10;
}

void I2C::ChangeI2CSpeed(UCHAR const div)
{
	m_clkdiv=div;
	Initialize();
}


//send slave address to the IIC bus......
BOOL I2C::Start()
{
	int times;
	BOOL IsTimeOver=TRUE;
	//transmit the slave address to the bus
	s2410IIC->rIICDS = m_ChipAddr;

	if(m_ChipAddr&0x01)
	{
		s2410IIC->rIICSTAT = IICSTAT_MRCV_START_OUTEN; //(2<<6) | (1<<5) | (1<<4);
		s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);//this is for read operation
	}
	else
	{
		s2410IIC->rIICSTAT = IICSTAT_MSND_START_OUTEN; //(3<<6) | (1<<5) | (1<<4);
	}
	//wait for operation complished...
	times=TIME_OUT;
	while(times-->0)
	{
		if((s2410IIC->rIICCON&0x10)!=0)
		{
			IsTimeOver=FALSE;
			break;
		}
	}
	if(IsTimeOver)
	{
		if(m_ChipAddr&0x01)
			s2410IIC->rIICSTAT = IICSTAT_MRCV_STOP_OUTEN; //(2<<6) | (0<<5) | (1<<4);
		else
			s2410IIC->rIICSTAT = IICSTAT_MSND_STOP_OUTEN; //(3<<6) | (0<<5) | (1<<4);
		//resume the operation:
		s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);
		for(int i=0;i<5000;i++)
			;
		RETAILMSG(1,(_T("Start:Time out!\n")));
		return (FALSE);
	}
	//if Arbitration and ACK success...
	if((s2410IIC->rIICSTAT&0x09)==0)
	{
		return (TRUE);
	}
	else
	{
		if(m_ChipAddr&0x01)
			s2410IIC->rIICSTAT = IICSTAT_MRCV_STOP_OUTEN; //(2<<6) | (0<<5) | (1<<4);
		else
			s2410IIC->rIICSTAT = IICSTAT_MSND_STOP_OUTEN; //(3<<6) | (0<<5) | (1<<4);
		s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);
		for(int i=0;i<5000;i++)
			;
		return (FALSE);
	}
	

}

//Stop IIC operation......
void I2C::Stop(BOOL IsSend)
{
	if(IsSend)
	{
		s2410IIC->rIICSTAT = IICSTAT_MSND_STOP_OUTEN; //(3<<6) | (0<<5) | (1<<4);
	}
	else
	{
		s2410IIC->rIICSTAT = IICSTAT_MRCV_STOP_OUTEN; //(2<<6) | (0<<5) | (1<<4);
	}
	s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);

	for(int i=0;i<5000;i++)
		;

}

//send a-byte data to the slave device......
BOOL I2C::SendByte(UCHAR data)
{
	int i=0;
	int times=0;
	BOOL IsTimeOver=TRUE;
	s2410IIC->rIICDS = data;

	s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);

	//wait for the data put on the bus......
	times=TIME_OUT;
	while(times-->0)
	{
		if((s2410IIC->rIICCON&0x10)!=0)
		{
			IsTimeOver=FALSE;
			break;
		}
	}
	if(IsTimeOver)
	{
		s2410IIC->rIICSTAT = IICSTAT_MSND_STOP_OUTEN; //(3<<6) | (0<<5) | (1<<4);
		s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);
		for(int i=0;i<5000;i++)
			;
		RETAILMSG(0,(_T("SendByte:Time out!\n")));
		return (FALSE);
	}
	//if arbitration and ACK success......
	if((s2410IIC->rIICSTAT&0x09)==0)
	{
		return (TRUE);
	}
	else
	{
		s2410IIC->rIICSTAT = IICSTAT_MSND_STOP_OUTEN; //(3<<6) | (0<<5) | (1<<4);
		s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);
		for(int i=0;i<5000;i++)
			;
		return (FALSE);
	}
}


BOOL I2C::RcvByte(UCHAR *data,BOOL IsSendACK)
{
	int times;
	BOOL IsTimeOver=TRUE;
	if(IsSendACK)
		s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);
	else
		s2410IIC->rIICCON = IICCON_ACKDIS_INTEN_RESUME; //(0<<7) | (1<<6) | (1<<5) | (0<<0);
	
	times=TIME_OUT;
	while(times-->0)
	{
		if((s2410IIC->rIICCON&0x10)!=0)
		{
			IsTimeOver=FALSE;
			break;
		}
	}
	if(IsTimeOver)
	{
		s2410IIC->rIICSTAT = IICSTAT_MRCV_STOP_OUTEN; //(2<<6) | (0<<5) | (1<<4);
		s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);
		for(int i=0;i<5000;i++)
			;
		RETAILMSG(1,(_T("RcvByte:Time out!\n")));
		return (FALSE);
	}
	if((s2410IIC->rIICSTAT&0x08)==0)
	{
		*data=s2410IIC->rIICDS;
		return (TRUE);
	}
	else
	{
		s2410IIC->rIICSTAT = IICSTAT_MRCV_STOP_OUTEN; //(2<<6) | (0<<5) | (1<<4);
		s2410IIC->rIICCON = IICCON_ACKEN_INTEN_RESUME; //(1<<7) | (1<<6) | (1<<5) | (0<<0);
		for(int i=0;i<5000;i++)
			;
		return (FALSE);
	}
}

BOOL I2C::SetOneReg(UCHAR Offset,UCHAR *dat)
{
	m_ChipAddr &= 0xFE;
	if(!Start())
	    return (FALSE);
	    
	if(!SendByte(Offset))
	    return (FALSE);
	    
	if(!SendByte(*dat))
	    return (FALSE);
	    
	Stop(TRUE);
	
	return (TRUE);
}

BOOL I2C::GetOneReg(UCHAR Offset,UCHAR *dat)
{
	m_ChipAddr &= 0xFE;		//write data
	if(!Start())
	    return (FALSE);
	   
	if(!SendByte(Offset))
	    return (FALSE);
	
	m_ChipAddr |= 0x01;	
    if(!Start())
	    return (FALSE);
	    
	if(!RcvByte(dat,FALSE))
	    return (FALSE);
	    
	Stop(FALSE);
	
	return (TRUE);
}

BOOL I2C::SetReg(UCHAR Offset,UCHAR *dat)
{
	int times=TRY_TIMES;
	while(times-->0)
	{
		if(SetOneReg(Offset,dat))
		{
			return TRUE;
		}
		ReInitialize();
	}
	return FALSE;
}

BOOL I2C::GetReg(UCHAR Offset,UCHAR *dat)
{
	int times=TRY_TIMES;
	while(times-->0)
	{
		if(GetOneReg(Offset,dat))
		{
			return TRUE;
		}
		ReInitialize();
	}
	return FALSE;
}

BOOL I2C::SetMultiBytes(UCHAR Offset,UCHAR Num,UCHAR* dat)
{
	//send slave device address on bus....
	m_ChipAddr &= 0xFE;
	if(!Start())
	{
		if(!Start())
			return (FALSE);
	}

	//send offset to the slave device...
	if(!SendByte(Offset))
		return (FALSE);

	//send data to the slave device...
	for(int i=0;i<Num;i++)
	{
		if(!SendByte(*dat))
			return (FALSE);
		dat++;
	}

	//stop the IIC bus
	Stop(TRUE);

	return (TRUE);
}

BOOL I2C::GetMultiBytes(UCHAR Offset,UCHAR Num,UCHAR* dat)
{
	UCHAR temp;
	//send slave address on the bus...
	m_ChipAddr &= 0xFE;
	if(!Start())
	{
		if(!Start())
			return (FALSE);
	}
	//send offset to the slave device...
	if(!SendByte(Offset))
		return (FALSE);

	//restart IIC bus...
	m_ChipAddr |= 0x01;
	if(!Start())
		return (FALSE);
	//read data from slave device...
	for(int i=0;i<Num;i++)
	{
		if(!RcvByte(dat,TRUE))
			return (FALSE);
		dat++;
	}
	
	if(!RcvByte(&temp,FALSE))
		return false;
	for(int j=0;j<5000;j++)
		;

	//Stop IIC bus...
	Stop(FALSE);

	return (TRUE);

}


//wrapped functions
BOOL I2C::SetMultiRegs(UCHAR Offset,UCHAR Num,UCHAR *dat)
{
	return SetMultiBytes(Offset,Num,dat);
}

BOOL I2C::GetMultiRegs(UCHAR Offset,UCHAR Num,UCHAR *dat)
{
	return GetMultiBytes(Offset,Num,dat);
}

UINT I2C::Test()
{
	UCHAR reg,val,val2;
	BOOL IsOk=TRUE;
	int time,Errors;

	Errors=0;
	for(time=0;time<10;time++)
	{
	RETAILMSG(1,(_T("Write index test:\n")));
	for(reg=0x10;reg<0x70;reg++)
	{
		SetReg(reg,&reg);
		GetReg(reg,&val);
		if(reg!=val)
		{
			RETAILMSG(1,(_T("T1:Set reg[0x%.2x]=0x%.2x,but Get reg[0x%.2x]=0x%.2x\n"),reg,reg,reg,val));
			Errors++;
			IsOk=FALSE;
		}
	}
	RETAILMSG(1,(_T("Write de-index test:\n")));
	for(reg=0x6F;reg>0x0F;reg--)
	{
		val2=0x80-reg;
		SetReg(reg,&val2);
		GetReg(reg,&val);
		if(val2!=val)
		{
			RETAILMSG(1,(_T("T2:Set reg[0x%.2x]=0x%.2x,but Get reg[0x%.2x]=0x%.2x\n"),reg,val2,reg,val));
			Errors++;
			IsOk=FALSE;
		}
	}
	RETAILMSG(1,(_T("Write 0x00 test:\n")));
	for(reg=0x10;reg<0x70;reg++)
	{
		val2=0x00;
		SetReg(reg,&val2);
		GetReg(reg,&val);
		if(val2!=val)
		{
			RETAILMSG(1,(_T("T3:Set reg[0x%.2x]=0x%.2x,but Get reg[0x%.2x]=0x%.2x\n"),reg,val2,reg,val));
			Errors++;
			IsOk=FALSE;
		}
	}
	RETAILMSG(1,(_T("Write 0x55 test:\n")));
	for(reg=0x10;reg<0x70;reg++)
	{
		val2=0x55;
		SetReg(reg,&val2);
		GetReg(reg,&val);
		if(val2!=val)
		{
			RETAILMSG(1,(_T("T3:Set reg[0x%.2x]=0x%.2x,but Get reg[0x%.2x]=0x%.2x\n"),reg,val2,reg,val));
			Errors++;
			IsOk=FALSE;
		}
	}
	RETAILMSG(1,(_T("Write 0xAA test:\n")));
	for(reg=0x10;reg<0x70;reg++)
	{
		val2=0xAA;
		SetReg(reg,&val2);
		GetReg(reg,&val);
		if(val2!=val)
		{
			RETAILMSG(1,(_T("T3:Set reg[0x%.2x]=0x%.2x,but Get reg[0x%.2x]=0x%.2x\n"),reg,val2,reg,val));
			Errors++;
			IsOk=FALSE;
		}
	}
	RETAILMSG(1,(_T("Write 0xFF test:\n")));
	for(reg=0x10;reg<0x70;reg++)
	{
		val2=0xFF;
		SetReg(reg,&val2);
		GetReg(reg,&val);
		if(val2!=val)
		{
			RETAILMSG(1,(_T("T3:Set reg[0x%.2x]=0x%.2x,but Get reg[0x%.2x]=0x%.2x\n"),reg,val2,reg,val));
			Errors++;
			IsOk=FALSE;
		}
	}

	}

	if(IsOk)
		RETAILMSG(1,(_T("Test passed!\n")));
	else
		RETAILMSG(1,(_T("Test failed!\n")));
	RETAILMSG(1,(_T("*****************************%d Errors*****************************\n"),Errors));

	return 0;
}

⌨️ 快捷键说明

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