⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2cdrv.c

📁 此为ESS 8381 I2C驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
                                        both SCL and SDA are high */        i2c_start(cptr);                    /* start condition */        i2c_writebyte(cptr, cptr->dev_addr);  /* control byte */	if( addr >= 0 ) {	    i2c_writebyte(cptr, 0x0);		/* starting address */	    i2c_writebyte(cptr, w_addr);		/* starting address */	}        for (i = 0; i < n; i++) {            i2c_writebyte(cptr, s[i]);        }        i2c_stop(cptr);                     /* stop condition */        wait_timer(cptr->tWR);          /* write cycle time */        if (!timeout)            return(0);    }    return(-1);}#endif /* REAL_TIME_CLK *//****************************************************  Read n bytes from the i2c device specified by  its device id.  No subaddress is specified.  arguments:	dev_id	device id read	n	no. of bytes to be written	s	array of storing n data to be read   return:	0 	okay (got ack)	-1	error (no ack)*****************************************************/int I2C_arrayread(int dev_id, int addr, int n, unsigned char *s){    int 	i, rt;    uchar	w_addr = (uchar)(addr & 0xff);    int 	tmp = (n-1);    IIC_CONFIG 	*cptr;#ifdef BIG_E2PROM    uchar hw_addr = (uchar)(((addr & 0x700)>>7)&0x0e);#endif    /* ptr to device parameters */    cptr = i2c_dev + dev_id;     for (rt = 0; rt < TRY_COUNT; rt++) {	/* try again if no ack */        timeout = 0;                    /* reset timeout */        wait_timer(cptr->tBUF);         /* bus free time:                                        both SCL and SDA are high */	if( addr >= 0 ) {	    i2c_start(cptr);                      /* start condition */#ifdef BIG_E2PROM       if(addr>255) {            i2c_writebyte(cptr, (cptr->dev_addr)|hw_addr);         } else            i2c_writebyte(cptr, cptr->dev_addr);#else	    i2c_writebyte(cptr, cptr->dev_addr);  /* control byte: for write */#endif	    i2c_writebyte(cptr, w_addr);          /* word address */	}        i2c_start(cptr);                    /* start condition */#ifdef BIG_E2PROM       if(addr>255) {            i2c_writebyte(cptr, ((cptr->dev_addr)|hw_addr) | 0x01);         } else        i2c_writebyte(cptr, (cptr->dev_addr) | 0x01);#else        i2c_writebyte(cptr, (cptr->dev_addr) | 0x01);#endif                                        /* control byte: for read */        for (i = 0; i < tmp; i++) {            s[i] = i2c_readbyte(cptr);            i2c_ack(cptr, 2);			/* give ack */        }        s[n-1] = i2c_readbyte(cptr);        i2c_ack(cptr, 0); 		/* ack clock cycle: 				no ack is needed for last read */        i2c_stop(cptr);                     /* stop condition */        if (!timeout)                                                return(0);                  /* data read */    }    return(-1);}#ifdef REAL_TIME_CLK /****************************************************  Read n bytes from the i2c device specified by  its device id.  No subaddress is specified.  arguments:	dev_id	device id read	n	no. of bytes to be written	s	array of storing n data to be read   return:	0 	okay (got ack)	-1	error (no ack)*****************************************************/int RtcI2CArrayRead(int dev_id, int addr, int n, unsigned char *s){    int 	i, rt;    uchar	w_addr = (uchar)(addr & 0xff);    int 	tmp = (n-1);    IIC_CONFIG 	*cptr;    /* ptr to device parameters */    cptr = i2c_dev + dev_id;     for (rt = 0; rt < TRY_COUNT; rt++) {	/* try again if no ack */        timeout = 0;                    /* reset timeout */        wait_timer(cptr->tBUF);         /* bus free time:                                        both SCL and SDA are high */	if( addr >= 0 ) {	    i2c_start(cptr);                      /* start condition */	    i2c_writebyte(cptr, cptr->dev_addr);  /* control byte: for write */	    i2c_writebyte(cptr, 0x0);          /* word address */	    i2c_writebyte(cptr, w_addr);          /* word address */	}        i2c_start(cptr);                    /* start condition */        i2c_writebyte(cptr, (cptr->dev_addr) | 0x01);                                        /* control byte: for read */        for (i = 0; i < tmp; i++) {            s[i] = i2c_readbyte(cptr);            i2c_ack(cptr, 2);			/* give ack */        }        s[n-1] = i2c_readbyte(cptr);        i2c_ack(cptr, 0); 		/* ack clock cycle: 				no ack is needed for last read */        i2c_stop(cptr);                     /* stop condition */        if (!timeout)                                                return(0);                  /* data read */    }    return(-1);}#endif /* REAL_TIME_CLK *//****************************************************  Acknowledge polling to see if the write cycle  is finished or not.  arguments:     	dev_id          device id  return:                                    	1              device acknowledge 	0              device not acknowledge*****************************************************/int I2C_ackpolling(int dev_id){    int tmp, stime;    IIC_CONFIG *cptr;    /* ptr to device parameters */        cptr = i2c_dev + dev_id;    stime = mvd[riface_timer2];    while (1) {			/* polling */	timeout = 0;	wait_timer(cptr->tBUF);	i2c_start(cptr);	i2c_writebyte(cptr, cptr->dev_addr);	need_to_stop = 0; 	/* reset the flag after one attempt */	if (!timeout) {	/* got ack */	    return(1);			}	else {			/* no ack */	    tmp = mvd[riface_timer2] - stime; 	    if (tmp < 0)		 	tmp += -timer2_period;	    if (tmp >= cptr->poll_wtime) {		return(0);	/* no ack (exit after timeout) */	    }	}    }}/* * Local Functions *//****************************************************  set and wait till scl is really high.  arguments:	*cptr	ptr to the current device parameters.  return:*****************************************************/static void i2c_raise_scl(IIC_CONFIG *cptr){    cptr->SCL_set(1);    while (1) {	if (cptr->SCL_sense()) break;    }}/****************************************************  I2C start condition.  arguments:	*cptr	ptr to the current device parameters.	  return:*****************************************************/static void i2c_start(IIC_CONFIG *cptr){    if (!need_to_stop) {        cptr->SDA_set(1);			/* SDA high */#ifndef CHEAT        wait_timer(cptr->tLOW);			/* SCL low time */#endif        i2c_raise_scl(cptr);			/* SCL high */        wait_timer((cptr->tR)+(cptr->tSU_STA));	/* SCL rise time +						start condition setup time */        cptr->SDA_set(0);			/* SDA low */        wait_timer((cptr->tF)+(cptr->tHD_STA));	/* SDA fall time +						start condition hold time */        cptr->SCL_set(0);			/* SCL low */#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);			/* SDA low */#ifndef CHEAT    wait_timer(cptr->tLOW);		/* SCL low time */#endif    i2c_raise_scl(cptr);		/* SCL high */    wait_timer((cptr->tR)+(cptr->tSU_STO));						/* SCL rise time +					stop condition setup time */    cptr->SDA_set(1);			/* SDA high */#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 defined(BD_ABELA3) || defined(BD_HERTZ)    SET_VFD_STROBE;#endif     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 high */	    }	    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);	/* SDA high */	#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);	    wait_timer(cptr->tHIGH);	/* SCL rise time and high time */	    ack_starttime = mvd[riface_timer2];						/* ack start time */            while (1) {	        if (!(cptr->SDA_sense())) {		    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) {		        timeout++;	 	        no_ack++;		        break;		/* acknowledge timeout */		    }	        }	    }        }        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 tristate */               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) || defined(BD_HERTZ)    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);}#endif /* IIC */int RDS_I2C_arrayread(int dev_id, int n, unsigned char *s){    int 	i, rt;    int 	tmp = (n-1);    IIC_CONFIG 	*cptr;if(dev_id <0)	return 0;    /* ptr to device parameters */    cptr = i2c_dev + dev_id;     for (rt = 0; rt < TRY_COUNT; rt++) {	/* try again if no ack */        timeout = 0;                    /* reset timeout */        wait_timer(cptr->tBUF);         /* bus free time:                                        both SCL and SDA are high */        i2c_start(cptr);                    /* start condition */        i2c_writebyte(cptr, (cptr->dev_addr) | 0x01);                                        /* control byte: for read */        for (i = 0; i < tmp; i++) {            s[i] = i2c_readbyte(cptr);            i2c_ack(cptr, 2);			/* give ack */        }        s[n-1] = i2c_readbyte(cptr);        i2c_ack(cptr, 0); 		/* ack clock cycle: 				no ack is needed for last read */        i2c_stop(cptr);                     /* stop condition */        if (!timeout)                                                return(0);                  /* data read */    }    return(-1);}int RDS_I2C_arraywrite(int dev_id, int n, uchar *s){    int 	i, rt;  //  uchar	w_addr = (uchar)(addr & 0xff);    IIC_CONFIG  *cptr;if(dev_id < 0)	return 0;     /* ptr to device parameters */    cptr = i2c_dev + dev_id;     for (rt = 0; rt < TRY_COUNT; rt++) {	/* try again if no ack */        timeout = 0;                    /* reset timeout */        wait_timer(cptr->tBUF);         /* bus free time:                                        both SCL and SDA are high */        i2c_start(cptr);                    /* start condition */#ifdef BIG_E2PROM#else        i2c_writebyte(cptr, cptr->dev_addr);  /* control byte */#endif        for (i = 0; i < n; i++) {            i2c_writebyte(cptr, s[i]);        }        i2c_stop(cptr);                     /* stop condition */        wait_timer(cptr->tWR);          /* write cycle time */        if (!timeout)            return(0);    }    return(-1);}

⌨️ 快捷键说明

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