www.pudn.com > DSP5502_audio_loopback.rar > E2PROM_Function.c
/********************************************************************************/ /* */ /* Filename: E2PROM_Function.c */ /* Function: Realize E2PROM`s writing and reading operation */ /* */ /********************************************************************************/ #include/********************************************************************************/ /* MODULE.NAME... I2C */ /* FUNCTIONNAME...... I2C_Write() */ /* DATE CREATED.. Sun 08/20/2004 */ /********************************************************************************/ void MyI2C_setup(I2C_Setup *Init) { int old_intm; Uint16 IPSC_calc; old_intm = IRQ_globalDisable(); /* 将下面的IRS域作了修改,让IIC模块处于复位状态,然后进行时钟的配置 */ I2C_RSET(I2CMDR,I2C_I2CMDR_RMK(Init->free,0,0,0,1,1,Init->addrmode,0,Init->dlb,0,0,0,Init->bitbyte)); /* set own address */ I2C_RSET(I2COAR,Init->ownaddr); /* if slave, need to specify own address */ /* calculating the IPSC value */ IPSC_calc = (Init->sysinclock)/12; /* must correct rounding issue */ I2C_RSET(I2CPSC,IPSC_calc); /* calculating the ICCLKL and ICCLKH register values */ I2C_RSET(I2CCLKL,15); I2C_RSET(I2CCLKH,15); /* 使能IIC模块 */ I2C_FSET(I2CMDR,IRS,1); IRQ_globalRestore(old_intm); } /* end of init */ int MyI2C_Write(Uint16 *data,int length,int master,Uint16 slaveaddress,int transfermode,int timeout) { int i,j,k,l,m; int old_intm; Uint16 temp=1; //old_intm = IRQ_globalDisable(); /* set in transmit mode */ I2C_FSET(I2CMDR,TRX,1); /* set the count register */ I2C_RSET(I2CCNT,length); if (master==1) { I2C_RSET(I2CSAR,slaveaddress); /* specify slave address */ I2C_FSET(I2CMDR,MST,1); /* turn master mode on */ /* setting the transfer mode */ if (transfermode==1) { /* S-A-D..(n)..D-P mode */ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,1); } else if (transfermode==2) { /* S-A-D..(n)..D mode (repeat n times)*/ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,0); } else if (transfermode==3) { /* S-A-D-D-D ... (repeat continuous) mode */ I2C_FSET(I2CMDR,RM,1); I2C_FSET(I2CMDR,STP,0); } else { /* if user specifies something else, go to idle mode */ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,0); } } /* end if master */ else { I2C_FSET(I2CMDR,MST,0); /* if not master, set to slave */ } /* end set up */ old_intm = IRQ_globalDisable(); for (i=0;i<=timeout;i++) { /* check for bus busy */ temp=I2C_FGET(I2CSTR,BB); if (temp==0) break; } IRQ_globalRestore(old_intm); if (i>=timeout) { /* bus busy timeout error */ //IRQ_globalRestore(old_intm); return 1; } for (m=0;m<=timeout;m++) { /* check for DXR status before first write*/ temp=I2C_FGET(I2CSTR,XRDY); if (temp==1) break; } if (m>=timeout) { //IRQ_globalRestore(old_intm); return 2; /* time out for transmit DXR ready */ } I2C_RSET(I2CDXR,*data++); /* put first data value in DXR */ I2C_FSET(I2CMDR,STT,1); /* generate start condition */ for (k=1;k =timeout) { //IRQ_globalRestore(old_intm); return 3; /* No acknowledge bit is set, NACK error */ } for (m=0;m<=timeout;m++) { /* check for DXR status */ temp=I2C_FGET(I2CSTR,XRDY); if (temp==1) break; } if (m>=timeout) { //IRQ_globalRestore(old_intm); return 4; /* time out for transmit DXR ready */ } I2C_RSET(I2CDXR,*data++); /* put next data value in DXR */ } /* end of for loop */ for (j=0;j<10;j++) { /* last delay loop for last data transferred*/ for (i=0;i<32000;i++) { asm (" NOP"); } } for (l=0;l<=timeout;l++) { /* check for NACK status for last data byte transferred*/ temp=I2C_FGET(I2CSTR,NACK); if (temp==0) break; } if (l>=timeout) { //IRQ_globalRestore(old_intm); return 5; /* No acknowledge bit is set, NACK error */ } //IRQ_globalRestore(old_intm); return 0; } /* end of I2C_Write */ /********************************************************************************/ /* MODULE.NAME... I2C */ /* FUNCTIONNAME...... I2C_Read() */ /* DATE CREATED.. Sun 08/20/2004 */ /********************************************************************************/ int MyI2C_Read(Uint16 *data,int length,int master,Uint16 slaveaddress,int transfermode,int timeout, int checkbus) { int i,j,k,m; int old_intm; Uint16 temp; //old_intm = IRQ_globalDisable(); /* set in receive mode */ I2C_FSET(I2CMDR,TRX,0); if (master==1) { I2C_RSET(I2CSAR,slaveaddress); /* specify slave address */ I2C_FSET(I2CMDR,MST,1); /* turn master mode on */ /* setting the transfer mode */ if (transfermode==1) { /* S-A-D..(n)..D-P mode */ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,1); I2C_RSET(I2CCNT,length); /* setting the data count in the ICCNT register */ } else if (transfermode==2) { /* S-A-D..(n)..D mode (repeat n times)*/ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,0); } else if (transfermode==3) { /* S-A-D-D-D ... (repeat continuous) mode */ I2C_FSET(I2CMDR,RM,1); I2C_FSET(I2CMDR,STP,0); } else { /* if user specifies something else, go to idle mode */ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,0); } } /* end if master */ else { I2C_FSET(I2CMDR,MST,0); /* if not master, set to slave */ } /* end set up */ if (checkbus==1) { old_intm = IRQ_globalDisable(); for (i=0;i<=timeout;i++) { /* check for bus busy */ temp=I2C_FGET(I2CSTR,BB); if (temp==0) break; } IRQ_globalRestore(old_intm); if (i>=timeout) /* bus busy timeout error */ return 1; } /* end of bus busy */ /* generate start condition */ I2C_FSET(I2CMDR,STT,1); /* delay loop to receive data */ for (i=0;i<32000;i++) { asm (" NOP"); } for (j=0;j<=timeout;j++) { /* check for DRR status */ temp=I2C_FGET(I2CSTR,RRDY); if (temp==1) break; } if (j>=timeout) return 2; /* time out for receive DRR ready */ *data++ = I2C_RGET(I2CDRR); /* put first data value in DXR */ for (k=1;k =timeout) return 4; /* time out for transmit DRR ready */ *data++ = I2C_RGET(I2CDRR); /* put next data value in DXR */ } /* end of for loop */ for (i=0;i<32000;i++) /* last delay loop */ { asm (" NOP"); } //IRQ_globalRestore(old_intm); return 0; } /* end of I2C_Read */ /********************************************************************************/ /* MODULE.NAME... I2C */ /* FUNCTIONNAME...... Set_WorkMode() */ /* DATE CREATED.. Sun 08/20/2004 */ /********************************************************************************/ void Set_WorkMode(int Master, Uint16 SlaveAddress, int TransferMode ) { /* set in transmit mode */ I2C_FSET(I2CMDR,TRX,1); /* set the count register */ I2C_RSET(I2CCNT,4); /* length set to 4 */ if (Master == 1) { I2C_RSET(I2CSAR,SlaveAddress); /* specify slave address */ I2C_FSET(I2CMDR,MST,1); /* turn master mode on */ /* setting the transfer mode */ if (TransferMode == 1) { /* S-A-D..(n)..D-P mode */ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,1); } else if (TransferMode == 2) { /* S-A-D..(n)..D mode (repeat n times)*/ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,0); } else if (TransferMode == 3) { /* S-A-D-D-D ... (repeat continuous) mode */ I2C_FSET(I2CMDR,RM,1); I2C_FSET(I2CMDR,STP,0); } else { /* if user specifies something else, go to idle mode */ I2C_FSET(I2CMDR,RM,0); I2C_FSET(I2CMDR,STP,0); } } /* end if master */ else { I2C_FSET(I2CMDR,MST,0); /* if not master, set to slave */ } /* end set up */ } /********************************************************************************/ /* MODULE.NAME... I2C */ /* FUNCTIONNAME...... Judge_I2cStatus() */ /* DATE CREATED.. Sun 08/20/2004 */ /********************************************************************************/ int Judge_I2cStatus(int TimeOut) { unsigned int i, m; int old_intm; Uint16 Temp = 1; old_intm = IRQ_globalDisable(); for (i = 0; i <= TimeOut; i++) { /* check for bus busy */ Temp = I2C_FGET(I2CSTR,BB); if (Temp == 0) break; } IRQ_globalRestore(old_intm); if (i >= TimeOut) { /* bus busy timeout error */ //IRQ_globalRestore(old_intm); return 1; } for (m = 0; m <= TimeOut; m++) { /* check for DXR status before first write*/ Temp = I2C_FGET(I2CSTR,XRDY); if (Temp == 1) break; } if (m >= TimeOut) { //IRQ_globalRestore(old_intm); return 2; /* time out for transmit DXR ready */ } return 0; } /********************************************************************************/ /* MODULE.NAME... I2C */ /* FUNCTIONNAME...... WriteSigWord_Deal() */ /* DATE CREATED.. Sun 08/20/2004 */ /********************************************************************************/ int WriteSigWord_Deal(int TimeOut) { unsigned int i, j, l, m; Uint16 Temp = 1; for (i=0;i<2000;i++) { for(j=0;j<1000;j++) /* delay loop */ { asm (" NOP"); } } for (l=0;l<=TimeOut;l++) { Temp=I2C_FGET(I2CSTR,NACK); /* check for NACK status */ if (Temp==0) break; } if (l>=TimeOut) { //IRQ_globalRestore(old_intm); return 3; /* No acknowledge bit is set, NACK error */ } for (m=0;m<=TimeOut;m++) { /* check for DXR status */ Temp=I2C_FGET(I2CSTR,XRDY); if (Temp==1) break; } if (m>=TimeOut) { //IRQ_globalRestore(old_intm); return 4; /* time out for transmit DXR ready */ } return 0; } /********************************************************************************/ /* MODULE.NAME... I2C */ /* FUNCTIONNAME...... LastByte_Deal() */ /* DATE CREATED.. Sun 08/20/2004 */ /********************************************************************************/ int LastByte_Deal(int TimeOut) { int i,j,l; Uint16 Temp = 1; for (j=0;j<10;j++) { /* last delay loop for last data transferred*/ for (i = 0; i < 32000; i++) { asm (" NOP"); } } for (l=0;l<=TimeOut;l++) { /* check for NACK status for last data byte transferred*/ Temp = I2C_FGET(I2CSTR,NACK); if (Temp == 0) break; } if (l >= TimeOut) { //IRQ_globalRestore(old_intm); return 5; /* No acknowledge bit is set, NACK error */ } return 0; } /********************************************************************************/ /* MODULE.NAME... I2C */ /* FUNCTIONNAME...... I2C_WriteSigWord() */ /* DATE CREATED.. Sun 08/20/2004 */ /********************************************************************************/ int MyI2C_WriteSigWord(unsigned int OwnAdd, unsigned int data, int master, Uint16 slaveaddress, int transfermode, int timeout) { unsigned int HighAdd, LowAdd; unsigned int HighByte, LowByte; int RetValue; HighAdd = (OwnAdd & 0xFF00)>>8; LowAdd = OwnAdd & 0x00FF; HighByte = (data & 0xFF00)>>8; LowByte = data & 0x00FF; /* Set I2C working mode */ Set_WorkMode(master, slaveaddress, transfermode); //old_intm = IRQ_globalDisable(); RetValue = Judge_I2cStatus(timeout); if(RetValue != 0) return(RetValue); /* put first data value in DXR */ I2C_RSET(I2CDXR,HighAdd); /* generate start condition */ I2C_FSET(I2CMDR,STT,1); RetValue = WriteSigWord_Deal(timeout); if(RetValue != 0) return(RetValue); /* put next data value in DXR */ I2C_RSET(I2CDXR,LowAdd); RetValue = WriteSigWord_Deal(timeout); if(RetValue != 0) return(RetValue); /* put next data value in DXR */ I2C_RSET(I2CDXR,HighByte); RetValue = WriteSigWord_Deal(timeout); if(RetValue != 0) return(RetValue); /* put next data value in DXR */ I2C_RSET(I2CDXR,LowByte); RetValue = LastByte_Deal(timeout); if(RetValue != 0) return(RetValue); return 0; } /* end of I2C_WriteSigWord */ /**************************************************************************************************/ // No more /**************************************************************************************************/