www.pudn.com > USBdiskRW.rar > Iic.c


#include "44b.h" 
#include "def.h" 
#include "option.h" 
#include "utils.h" 
#include "iic.h" 
 
#define WRDATA	    (1) 
#define POLLACK     (2) 
#define RDDATA	    (3) 
#define SETRDADDR   (4) 
 
#define IICBUFSIZE 0x20 
 
int x=0,y=0; 
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,save_F,save_PF; 
    static U8 data[256]; 
 
    printf("\nIIC EEPROM AT24C02 Read and Write Test\n"); 
 
    printf("\n\n注意由于本项测试使用了中断,所以必须将本项目的目标代码烧写入Flash的0地址\n"); 
    printf("这样Flash中才有中断向量,不过只需要烧入一次就行了,以后JTAG调试或网口下载运行本程序就没有问题了\n"); 
    printf("可以使用netload或者是comload下载本目标代码到SDRAM,然后用Prog 0烧写代码到Flash(不覆盖0地址跳转指令)\n\n"); 
 
    save_F=rPCONF; 
    save_PF=rPUPF; 
    rPCONF |=0xa;	//PF0:IICSCL, PF1:IICSDA 
    rPUPF |=0x3;	//pull-up disable 
 
    rINTMSK = BIT_GLOBAL ;	//disable INT 
	rINTCON = 0x5 ;		//无向量中断模式 
	rINTMOD = 0x0 ;		//All=IRQ mode 
    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; 
 
    printf("\nWrite 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; 
 
    printf("\nRead test data from KS24C080\n\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++) 
		    printf("%2x ",data[i*16+j]); 
		printf("\n"); 
    } 
     
    rPCONF=save_F; 
    rPUPF=save_PF; 
    rINTMSK = BIT_GLOBAL ;	//disable INT 
} 
 
 
 
/* 
case WRDATA: 
	    if((_iicDataCount--)==0) 
	    { 
		rIICSTAT=0xd0;	//stop MasTx condition  
		rIICCON=0xaf;	//重新开始 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. 
	    printf(" ; "); 
	    break; 
 
*/ 
 
void Wr24C040(U32 slvAddr,U32 addr,U8 data) 
{ 
    
    printf(" %d> ",x++); 
    _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); 
     printf("!"); 
      
    _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 
    } 
     printf("?"); 
    rIICSTAT=0xd0;  //stop MasTx condition  
    rIICCON=0xaf;   //resumes IIC operation.  
    Delay(1);	    //wait until stop condtion is in effect. 
 
    //write is completed. 
} 
 
 
/* 
 
case SETRDADDR: 
	    //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. 
	    printf(" ' "); 
	    break; 
*/ 
 
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; //rIICSTAT=1011,0000;从发送模式 
    rIICCON=0xaf;  //resumes IIC operation.    
    while(_iicDataCount!=-1); 
    printf("(r)"); 
    *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; 
	      printf(" . "); 
	    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 
		printf(" , "); 
	    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. 
	    printf(" ; "); 
	    break; 
 
	case SETRDADDR: 
	    //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. 
	    printf(" ' "); 
	    break; 
 
	default: 
	printf(" ~ "); 
	    break;	   
    } 
}