i2c_prom.c

来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 774 行 · 第 1/2 页

C
774
字号
#ifndef CHEAT        // wait_timer((cptr->tF)+(cptr->tLOW));	/* SCL fall time + SCL low time */#endif    }}/**************************************************** i2c_stop:        I2C stop condition.         arguments:		*cptr	ptr to the current device			parameters.        return:    *****************************************************/static void i2c_stop(IIC_CONFIG *cptr){    need_to_stop = 0;			/* reset "need_to_stop" */    cptr->SDA_set(0);			/*1 SDA low */#ifndef CHEAT    // wait_timer(cptr->tLOW);	/* SCL low time */#endif    i2c_raise_scl(cptr);		/*2 SCL high */    // wait_timer((cptr->tR)+(cptr->tSU_STO));	 /* SCL rise time + stop condition setup time */    cptr->SDA_set(1);			/*3 SDA 1 */#ifndef CHEAT    // wait_timer(cptr->tR);		/* SDA rise time */#endif}/**************************************************** i2c_writebyte:        Write a byte to I2C bus.         arguments:		*cptr	ptr to the current device			parameters.		c	a byte to be written			        return:    *****************************************************/static void i2c_writebyte(IIC_CONFIG *cptr, unsigned char c){    int i;    if (!need_to_stop) {        for (i = 0; i < 8; i++) {	    // wait_timer(cptr->tLOW);		/* SCL low time */            if (c & 0x80) {			/* most significant bit */       	       cptr->SDA_set(1);		/* SDA hi */	     }else {	        	cptr->SDA_set(0);		/* SDA low */            }#ifndef CHEAT           // wait_timer(cptr->tSU_DAT);		/* data in setup time */#endif	    i2c_raise_scl(cptr);		/* SCL high */ 	    // wait_timer((cptr->tR)+(cptr->tHIGH)); /* SCL rise time + SCL high time */           cptr->SCL_set(0);			/* SCL low */#ifndef CHEAT	    // wait_timer((cptr->tF)+(cptr->tHD_DAT));	/* SDA and SCL fall time + data in hold time */#endif            c <<= 1;        }       i2c_ack(cptr, 1);			/* get acknowledge */        if (timeout)	    need_to_stop = 1;        else 		    need_to_stop = 0;    }}/**************************************************** i2c_ack:        I2C acknowledge of byte transfer.         arguments:			*cptr	ptr to the current device			parameters.		mode	0 (no ack needed)					1 (get ack)			2 (give ack)        return:    		 0		okay (got ack)		-1		error (no ack)*****************************************************/static int i2c_ack(IIC_CONFIG *cptr, int mode){    int tmp;    int ack_starttime;    int k = -1;    if (!need_to_stop) {        if (mode == 1) {	/* get acknowledge */	    cptr->SDA_set(1);	/* 1 SDA TRISTATE_EAUX4 */	#ifndef CHEAT            // wait_timer((cptr->tR)+(cptr->tSU_DAT)); /* SDA rise time and setup time */#endif	    // wait_timer(cptr->tLOW);	/* SCL low time */	    i2c_raise_scl(cptr);		/* 2 SCL high */	    // wait_timer(cptr->tHIGH);	/* SCL rise time and high time */	    ack_starttime = mvd[riface_timer2]; /* ack start time */            while (1) {	        if (!(cptr->SDA_sense())) { // 3 wait SDA low		    k = 0;				           yes_ack++;		    break;		/* got acknowledge */	        }else {		    k = -1;		    tmp = mvd[riface_timer2] - ack_starttime;		    if (tmp < 0)			        tmp += -timer2_period;		    if (tmp >= cptr->ack_wtime) {  //16C		        timeout++;	 	        no_ack++;		        break;		/* acknowledge timeout */		    }	        }//	       AUD_service();  // cf	    }        }        else if (mode == 2) { 	/* acknowledge is needed */	    // wait_timer(cptr->tLOW);	/* SCL low time */	    cptr->SDA_set(0);		/* SDA low */   	    // wait_timer((cptr->tF)+(cptr->tSU_DAT));		    /* SDA fall time and setup time */	    // wait_timer(cptr->tLOW);	/* SCL low time */	    /* clock cycle for acknowledge */	    i2c_raise_scl(cptr);	/* SCL high */	    // wait_timer((cptr->tR)+(cptr->tHIGH));		    /* SDA and SCL rise time +	       SCL high time */        }else { 			/* no acknowledge is needed */             i2c_raise_scl(cptr);                /* SCL high */                // wait_timer((cptr->tR)+(cptr->tHIGH));   					     /* SDA and SCL rise time +                                             SCL high time */         }        cptr->SCL_set(0);		/* SCL low */        // wait_timer((cptr->tF)+(cptr->tLOW));						/* SCL fall time +   					SCL low time */	/* For mode 2, need to tristate SDA again. MY20010314 */	if( mode == 2 ) {	    cptr->SDA_set(1);		/* SDA hi */               // wait_timer((cptr->tR));	/* SCL rise time */	}    }    return(k);}/**************************************************** i2c_readbyte:        Read a byte from the I2C bus.          arguments:		*cptr 	ptr to the current device			parameters.        return:    		b		byte read*****************************************************/static uchar i2c_readbyte(IIC_CONFIG *cptr){    int i;    unsigned char b;#if defined(BD_ABELA3)    SET_VFD_STROBE;#endif    b = 0;    if (!need_to_stop) {        for (i = 0; i < 8; i++) {	    b <<= 1;	    // wait_timer(cptr->tAA);		/* data output delay time */	    i2c_raise_scl(cptr);			/* SCL high */            // wait_timer(cptr->tR);		/* SCL rise time */            if (cptr->SDA_sense())		/* SDA out */		        b |= 1;	    else	        b |= 0;  	    // wait_timer(cptr->tHIGH);		/* SCL high time */ 	    cptr->SCL_set(0);			/* SCL low */ 	    // wait_timer((cptr->tF)+(cptr->tDH)+(cptr->tLOW));						/* SCL fall time +						data out hold time +						clock low time */         }    }    return(b);}/****************************************************************** This is a driver to control the E2PROM.*******************************************************************//* for debug */#define EEPROM_TEST	 	0		/****************************************************************** Various Defines.*******************************************************************/#define EEPROM_ADDR             0xa0/****************************************************************** Variables.*******************************************************************/static int eeprom_timing[] = {        7000,   /* tAA     */        6700,   /* tBUF    */        4500,   /* tHD_STA */        6700,   /* tSU_STA */        6700,   /* tLOW    */        4500,   /* tHIGH   */           0,   /* tHD_DAT */         500,   /* tSU_DAT */        1000,   /* tR      */         300,   /* tF      */        6700,   /* tSU_STO */         300,   /* tDH     */    10000000    /* tWR: 10ms seems to be about right */}; static int eeprom_id = -1; 	/* device id for eeprom */static int prev_wcmd = 0;	/* = 1 (write cmd); = 0 (read cmd) */#if EEPROM_TEST/* for debug */static int i2c_ret   = 0;static int w_addr    = 0;static int w_data    = 0;static int r_addr    = 0;static int r_data    = 0;static int s_data[128];#endif /* EEPROM_TEST */ /****************************************************************** Function Definitions.*******************************************************************//*********************************************************************** * I2C SDA and SCL pins ***********************************************************************/void set_sda(int high){    if (high) { INPUT_I2C_DAT; } else { CLEAR_I2C_DAT; }   //    if (high) { TRISTATE_AUX5; } else { CLEAR_AUX5; }   }void set_scl(int high){    if (high) { INPUT_I2C_CLK; } else { CLEAR_I2C_CLK; }//    if (high) { TRISTATE_AUX7; } else { CLEAR_AUX7; }}int sense_sda(){    return((I2C_DAT_HIGH) ? 1:0); //   return((AUX5_HIGH) ? 1:0);}int sense_scl(){    return((I2C_CLK_HIGH) ? 1:0);//    return((AUX7_HIGH) ? 1:0);}/**************************************************** I2C_PROM_init:	Configure I2C parameters for the eeprom.*****************************************************/int I2C_PROM_init(){    	eeprom_id = I2C_config(EEPROM_ADDR, set_scl, set_sda,			sense_scl, sense_sda, eeprom_timing);    	if (eeprom_id==-1){    		EepromErr = 1;    		return(0);  // error eeprom    	}else{    		EepromErr = 0;    		return (1);    	}}/******************************************** Write a byte to E2PROM. parameter: addr - word-address (0 to 127)            data - 8-bit input data return:     0   - write okay            -1   - error,                   no acknowledge from E2PROM*********************************************/int i2c_e2prom_bywrite(uchar addr, uchar data){    int a, b;     if (prev_wcmd) {	/* ack polling */		a = I2C_ackpolling(eeprom_id);    }    else {		a = 1;    }    prev_wcmd = 1;	/* write command */    if (a) {	/* get ack or no polling is needed */		b = I2C_bytewrite(eeprom_id, addr, data);		return(b);    }    else {	/* no ack: device still busy */		return(-1);    }} /******************************************** Read a byte from E2PROM.  parameter: addr - word-address (0 to 127) return:     >=0 - output data            -1   - error,                   no acknowledge from E2PROM*********************************************/int i2c_e2prom_byread(uchar addr){    int a, b;     if (prev_wcmd) {	/* ack polling */		a = I2C_ackpolling(eeprom_id);    }    else {		a = 1;    }    prev_wcmd = 0;	/* read command */    if (a) {	/* get ack or no polling is needed */		b = I2C_byteread(eeprom_id, addr);	  	return(b);    }    else {	/* no ack: device still busy */		return(-1);    }}/****************************************************/#if EEPROM_TEST/* for debug */void I2C_driver_test(int mode){    int i;     switch(mode) {        case 1: /* config */            eeprom_id = I2C_config(EEPROM_ADDR, set_scl, set_sda,                        sense_scl, sense_sda, eeprom_timing);            break;        case 2: /* single byte write */            i2c_ret   = I2C_bytewrite(eeprom_id, w_addr, w_data);            break;        case 3: /* single byte read */            r_data    = I2C_byteread(eeprom_id, r_addr);            break;        case 4: /* 128 bytes write */            for (i = 0; i < 128; i++) {                i2c_ret = I2C_bytewrite(eeprom_id, i, (127-i));            }            break;        case 5: /* 128 bytes read */            for (i = 0; i < 128; i++) {                s_data[i] = I2C_byteread(eeprom_id, i);            }            break;        default:            break;    }}#endif /* EEPROM_TEST */#endif /* I2C_E2PROM */

⌨️ 快捷键说明

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