📄 i2c.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,®);
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 + -