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

📄 i2cdrv.c

📁 此为ESS 8381 I2C驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2001, ESS Technology, Inc. *//* SCCSID @(#)i2cdrv.c	1.32 06/06/03 *//* * $Log$ */#ifdef IIC/****************************************************************** This is a single generic I2C driver with api.*******************************************************************//* Header Files */#include "mvd.h"#include "common.h"#include "util.h"#include "ioport.h"#include "debug.h"#include "i2cdrv.h"	/* my header */#if defined(BD_ABELA3) || defined(BD_HERTZ)#include "vfd.cfg"#endif#define SET_RDS_SDA               SET_AUX0#define CLEAR_RDS_SDA           CLEAR_AUX0#define TRISTATE_RDS_SDA     TRISTATE_AUX0#define RDS_SDA_IS_HIGH       AUX0_HIGH#define SET_RDS_SCL                SET_AUX1#define CLEAR_RDS_SCL            CLEAR_AUX1#define TRISTATE_RDS_SCL      TRISTATE_AUX1#define RDS_CLK_IS_HIGH        AUX1_HIGH#if 1/*********************************************************************** * I2C SDA and SCL pins * When there are multiple I2C buses, each one will have a different * set of these functions. ***********************************************************************/void set_sda(int high){    if (high) { TRISTATE_RDS_SDA; } else { CLEAR_RDS_SDA; }}void set_scl(int high){    if (high) { TRISTATE_RDS_SCL; } else { CLEAR_RDS_SCL; }}int sense_sda(){    return((RDS_SDA_IS_HIGH) ? 1:0);}int sense_scl(){    return((RDS_CLK_IS_HIGH) ? 1:0);}#endif/****************************************************************** Various Defines.*******************************************************************/#define CHEAT#ifndef PRINTF#define PRINTF(x)#endif#define I2C_DEV_MAX		 3	/* maximum no. of device */#if defined(TVLIVE) && defined(REAL_TIME_CLK)#define I2C_DEV_MAX		 5	/* maximum no. of device */#elif defined(TVLIVE) || defined(REAL_TIME_CLK)#define I2C_DEV_MAX		 4	/* maximum no. of device */#endif#define TRY_COUNT		 5 	/* retry if no ack */#define I2C_TIME_NUM		13	/* total no. of time config */#define UPLIMIT			(0x80000000/(3*CPUCLK))	/* for ackpolling */#define wait_timer(x)		RISC_sleep_nsec(x)	/* waiting time *//* device specification */typedef struct {    int dev_addr;			/* device I2C address */    void (*SCL_set)(int);		/* SCL_set fn ptr     */    void (*SDA_set)(int);		/* SDA_set fn ptr     */    int (*SCL_sense)();			/* SCL_sense fn ptr   */    int (*SDA_sense)();			/* SDA_sense fn ptr   */    /* timing info */    int tAA;            /* SCL Low to SDA Data Out Valid.    */    int tBUF;           /* Time the Bus Must be Free before                           a New Transmission Can Start.     */    int tHD_STA;        /* Start Condition Hold Time.        */    int tSU_STA;        /* Start Condition Setup Time                           (for a Repeated Start Condition). */    int tLOW;           /* Clock Low Time.                   */    int tHIGH;          /* Clock High Time.                  */    int tHD_DAT;        /* Data In Hold Time.                */    int tSU_DAT;        /* Data In Setup Time.               */    int tR;             /* SDA and SCL Rise Time.            */    int tF;             /* SDA and SCL Fall Time.            */    int tSU_STO;        /* Stop Condition Setup Time.        */    int tDH;            /* Data Out Hold Time.               */    int tWR;            /* Write Cycle Time.                 */    /* timeout periods */    int poll_wtime;	/* ack-polling timeout 		     */    int ack_wtime;	/* ack timeout  		     */} IIC_CONFIG;/****************************************************************** Variables.*******************************************************************/static IIC_CONFIG 	i2c_dev[I2C_DEV_MAX];	/* device parameters      */ static int	  	i2c_dev_num = -1; 	/* device id used so far  */static int              timeout = 0;		/* acknowledge timeout    */static int		need_to_stop = 0; 	/* stop if no ack 	 *//* for debug */static int 		yes_ack = 0;static int		no_ack  = 0;/****************************************************************** Local Function Declarations.*******************************************************************/static void 	i2c_raise_scl(IIC_CONFIG *cptr);static void 	i2c_start(IIC_CONFIG *cptr);	/* start condition   */static void 	i2c_stop(IIC_CONFIG *cptr); 	/* stop condition    */static void 	i2c_writebyte(IIC_CONFIG *cptr, uchar c);static int  	i2c_ack(IIC_CONFIG *cptr, int mode);static uchar	i2c_readbyte(IIC_CONFIG *cptr);/****************************************************************** Function Definitions (Local and Global).*******************************************************************//****************************************************  Set up i2c parameters for each device and  assign a device id.  arguments:  	dev_addr	i2c device address	SCL_set		function to toggle SCL pin	SDA_set		function to toggle SDA pin	SCL_sense	function to sense SCL pin	SDA_sense	function to sense SDA pin	*time_array	devicetiming info  return:	dev_id		device id assigned     	*****************************************************/int I2C_config(    int 	dev_addr,    void 	(*SCL_set)(int),     void 	(*SDA_set)(int),    int 	(*SCL_sense)(),     int 	(*SDA_sense)(),    int 	*time_array){    int 	i;    int 	*p;    IIC_CONFIG 	*cptr;    PRINTF(( "I2C_config 0x%x\n", dev_addr ));    i2c_dev_num++;    if (i2c_dev_num >=  I2C_DEV_MAX) {	EPRINTF(("I2C_config: exceed max no. of devices!\n"));        return(-1);    }    /* configure device parameters */    cptr = i2c_dev + i2c_dev_num;    cptr->dev_addr 	= dev_addr;    cptr->SCL_set  	= SCL_set;    cptr->SDA_set  	= SDA_set;    cptr->SCL_sense  	= SCL_sense;    cptr->SDA_sense  	= SDA_sense;    p = &(cptr->tAA);	/* ptr to the first timing parameter */    for (i = 0; i < I2C_TIME_NUM; i++)	/* load timing parameters */	*(p++) = *(time_array++);    /* calculate wait time for I2C_ackpolling */    if (cptr->tWR >= UPLIMIT)	cptr->poll_wtime = 3 * ((cptr->tWR)/10000) * CPUCLK; 					/* if tWR is large */    else	cptr->poll_wtime = 3 * (cptr->tWR) * CPUCLK / 10000;    /* calculate wait time for i2c_ack */    cptr->ack_wtime = (cptr->tHIGH) * CPUCLK / 10000;    /* To confirm the device */    for (i=0; i<TRY_COUNT; i++) {        timeout = 0;	wait_timer(cptr->tBUF);        i2c_start(cptr);        i2c_writebyte(cptr, cptr->dev_addr);        i2c_stop(cptr);	wait_timer(cptr->tWR);        if (!timeout) return(i2c_dev_num);	    }    i2c_dev_num--;    return (-1);}/****************************************************  Write a byte to the i2c device specified by  its device id.   arguments:	dev_id 	device id 	addr	address to be written ( ignore if < 0 )	data	data to be written   return:	0	okay (got ack)	-1	error (no ack)	*****************************************************/int I2C_bytewrite(int dev_id, int addr, uchar data){    int 	i;    uchar	w_addr = (uchar)(addr & 0xff);    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 (i = 0; i < TRY_COUNT; i++) {   /* 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{        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 */#endif	if( addr >= 0 ) {	    i2c_writebyte(cptr, w_addr);          /* word address */	}        i2c_writebyte(cptr, data);            /* data */        i2c_stop(cptr);                     /* stop condition */#ifndef CHEAT        wait_timer(cptr->tWR);          /* write cycle time */#endif        if (!timeout)            return(0);    }        return(-1); /* timeout without acknowledge after several attempts */}    #ifdef REAL_TIME_CLK/****************************************************  Write a byte to the i2c device specified by  its device id.   arguments:	dev_id 	device id 	addr	address to be written ( ignore if < 0 )	data	data to be written   return:	0	okay (got ack)	-1	error (no ack)	*****************************************************/int RtcI2CByteWrite(int dev_id, int addr, uchar data){    int 	i;    uchar	w_addr = (uchar)(addr & 0xff);    IIC_CONFIG  *cptr;      /* ptr to device parameters */    cptr = i2c_dev + dev_id;    for (i = 0; i < TRY_COUNT; i++) {   /* 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);  /* control byte */	if( addr >= 0 ) {	    i2c_writebyte(cptr, 0x0);          /* word address */	    i2c_writebyte(cptr, w_addr);          /* word address */	}        i2c_writebyte(cptr, data);            /* data */        i2c_stop(cptr);                     /* stop condition */#ifndef CHEAT        wait_timer(cptr->tWR);          /* write cycle time */#endif        if (!timeout)            return(0);    }        return(-1); /* timeout without acknowledge after several attempts */}    #endif /* REAL_TIME_CLK */  /****************************************************  Read a byte from the i2c device specified by  its device id.  arguments:	dev_id	device id	addr	address to be read (ignore if < 0 )  return:	>= 0	data read 	-1	error (no ack)*****************************************************/int I2C_byteread(int dev_id, int addr){    int 	i;    uchar 	b;    uchar	w_addr = (uchar)(addr & 0xff);    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 (i = 0; i < TRY_COUNT; i++) {   /* 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 */        b = i2c_readbyte(cptr);             /* read one byte of data */        /* ack clock cycle: no ack is needed for read */        i2c_ack(cptr, 0);        i2c_stop(cptr);                     /* stop condition */        if (!timeout)            return(b);                  /* data read */    }    return(-1);                         /* timeout without acknowledge                                        after several attempts */}#ifdef REAL_TIME_CLK/****************************************************  Read a byte from the i2c device specified by  its device id.  arguments:	dev_id	device id	addr	address to be read (ignore if < 0 )  return:	>= 0	data read 	-1	error (no ack)*****************************************************/int RtcI2CByteRead(int dev_id, int addr){    int 	i;    uchar 	b;    uchar	w_addr = (uchar)(addr & 0xff);    IIC_CONFIG 	*cptr;     /* ptr to device parameters */    cptr = i2c_dev + dev_id;     for (i = 0; i < TRY_COUNT; i++) {   /* 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 */        b = i2c_readbyte(cptr);             /* read one byte of data */        /* ack clock cycle: no ack is needed for read */        i2c_ack(cptr, 0);        i2c_stop(cptr);                     /* stop condition */        if (!timeout)            return(b);                  /* data read */    }    return(-1);                         /* timeout without acknowledge                                        after several attempts */}#endif /* REAL_TIME_CLK *//****************************************************  Write n bytes to the i2c device specified by  its device id.  arguments:	dev_id	device id	addr	starting address to be written ( ignore if < 0 )	n	no. of bytes to be written 	s	array of n data to be written   return: 	0	okay (got ack)        	-1	error (no ack)*****************************************************/int I2C_arraywrite(int dev_id, int addr, int n, uchar *s){    int 	i, rt;    uchar	w_addr = (uchar)(addr & 0xff);    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 */        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 */#endif	if( addr >= 0 ) {	    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);}#ifdef REAL_TIME_CLK/****************************************************  Write n bytes to the i2c device specified by  its device id.  arguments:	dev_id	device id	addr	starting address to be written ( ignore if < 0 )	n	no. of bytes to be written 	s	array of n data to be written   return: 	0	okay (got ack)        	-1	error (no ack)*****************************************************/int RtcI2CArrayWrite(int dev_id, int addr, int n, uchar *s){    int 	i, rt;    uchar	w_addr = (uchar)(addr & 0xff);    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:

⌨️ 快捷键说明

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