www.pudn.com > hf44b0_TEST.rar > IIC.C
#include#include "..\inc\44b.h" #include "..\inc\44blib.h" #include "..\inc\def.h" #include "..\inc\iic.h" #define WRDATA (1) #define POLLACK (2) #define RDDATA (3) #define SETRDADDR (4) #define IICBUFSIZE 0x20 U8 _iicData[IICBUFSIZE]; volatile int _iicDataCount; volatile int _iicStatus; volatile int _iicMode; int _iicPt; void __irq IicInt(void); void Test_Iic(void) { unsigned int i,j; static U8 data[256]; Uart_Printf("[IIC Test using KS24C02]\n"); pISR_IIC=(unsigned)IicInt; rINTMSK=~(BIT_GLOBAL|BIT_IIC); rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xf); //Enable interrupt, IICCLK=MCLK/16, Enable ACK //40Mhz/16/(15+1) = 257Khz rIICADD=0x10; // S3C44B0X slave address rIICSTAT=0x10; Uart_Printf("Write test data into KS24C080\n"); for(i=0;i<256;i++) Wr24C040(0xa0,(U8)i,i); for(i=0;i<256;i++) data[i]=0; Uart_Printf("Read test data from KS24C080\n"); for(i=0;i<256;i++) Rd24C040(0xa0,(U8)i,&(data[i])); for(i=0;i<16;i++) { for(j=0;j<16;j++) Uart_Printf("%2x ",data[i*16+j]); Uart_Printf("\n"); } } void Wr24C040(U32 slvAddr,U32 addr,U8 data) { _iicMode=WRDATA; _iicPt=0; _iicData[0]=(U8)addr; _iicData[1]=data; _iicDataCount=2; rIICDS=slvAddr;//0xa0 rIICSTAT=0xf0; //MasTx,Start //Clearing the pending bit isn't needed because the pending bit has been cleared. while(_iicDataCount!=-1); _iicMode=POLLACK; while(1) { rIICDS=slvAddr; _iicStatus=0x100; rIICSTAT=0xf0; //MasTx,Start rIICCON=0xaf; //resumes IIC operation. while(_iicStatus==0x100); if(!(_iicStatus&0x1)) break; // when ACK is received } rIICSTAT=0xd0; //stop MasTx condition rIICCON=0xaf; //resumes IIC operation. Delay(1); //wait until stop condtion is in effect. //write is completed. } void Rd24C040(U32 slvAddr,U32 addr,U8 *data) { _iicMode=SETRDADDR; _iicPt=0; _iicData[0]=(U8)addr; _iicDataCount=1; rIICDS=slvAddr; rIICSTAT=0xf0; //MasTx,Start //Clearing the pending bit isn't needed because the pending bit has been cleared. while(_iicDataCount!=-1); _iicMode=RDDATA; _iicPt=0; _iicDataCount=1; rIICDS=slvAddr; rIICSTAT=0xb0; //MasRx,Start rIICCON=0xaf; //resumes IIC operation. while(_iicDataCount!=-1); *data=_iicData[1]; } void __irq IicInt(void) { U32 iicSt,i; rI_ISPC=BIT_IIC; iicSt=rIICSTAT; if(iicSt&0x8){} // when bus arbitration is failed. if(iicSt&0x4){} // when a slave address is matched with IICADD if(iicSt&0x2){} // when a slave address is 0000000b if(iicSt&0x1){} // when ACK isn't received switch(_iicMode) { case POLLACK: _iicStatus=iicSt; break; case RDDATA: if((_iicDataCount--)==0) { _iicData[_iicPt++]=rIICDS; rIICSTAT=0x90; //stop MasRx condition rIICCON=0xaf; //resumes IIC operation. Delay(1); //wait until stop condtion is in effect. //too long time... //The pending bit will not be set after issuing stop condition. break; } _iicData[_iicPt++]=rIICDS; //The last data has to be read with no ack. if((_iicDataCount)==0) rIICCON=0x2f; //resumes IIC operation with NOACK. else rIICCON=0xaf; //resumes IIC operation with ACK break; case WRDATA: if((_iicDataCount--)==0) { rIICSTAT=0xd0; //stop MasTx condition rIICCON=0xaf; //resumes IIC operation. Delay(1); //wait until stop condtion is in effect. //The pending bit will not be set after issuing stop condition. break; } rIICDS=_iicData[_iicPt++]; //_iicData[0] has dummy. for(i=0;i<10;i++); //for setup time until rising edge of IICSCL rIICCON=0xaf; //resumes IIC operation. break; case SETRDADDR: //Uart_Printf("[S%d]",_iicDataCount); if((_iicDataCount--)==0) { break; //IIC operation is stopped because of IICCON[4] } rIICDS=_iicData[_iicPt++]; for(i=0;i<10;i++); //for setup time until rising edge of IICSCL rIICCON=0xaf; //resumes IIC operation. break; default: break; } }