i2c_prom.c

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

C
774
字号
/* SCCSID @(#)i2cdrv.h	1.9 03/14/01 */#ifdef I2C_E2PROM/* Header Files */#include "mvd.h"#include "common.h"#include "util.h"#include "ioport.h"#include "debug.h"#include "sysinfo.h"/****************************************************************** Global Function Declarations.*******************************************************************/int	I2C_config(int dev_addr, void (*SCL_set)(int), void (*SDA_set)(int),		int (*SCL_sense)(), int (*SDA_sense)(),        	int *time_array);int     I2C_bytewrite(int, int, uchar);int	I2C_ackpolling(int);int     I2C_byteread(int, int );uchar EepromErr;/****************************************************************** Global Variables.*******************************************************************//****************************************************************** Global Function Declarations.*******************************************************************/int 		I2C_PROM_init();	/* Configure parameters */int		i2c_e2prom_bywrite(uchar, uchar);int		i2c_e2prom_byread(uchar);#if EEPROM_TESTvoid		I2C_driver_test(int mode);					/* for debug */#endif/*******************************************************************  IC2_E2PROM Constant Declaration******************************************************************//*******************************************************************  Note:*       If there are the value 'zj' in the first 2 byte of E2PROM, it means*  that E2PROM has been initialized, then we should read out stored values*  and use them.**********************************************************************/ /****************************************************************** This is a single generic I2C driver with api.*******************************************************************//****************************************************************** Various Defines.*******************************************************************/#define CHEAT #ifndef PRINTF#define PRINTF(x)#endif#define I2C_DEV_MAX		 3	/* maximum no. of device */#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_a_bit(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=1;#if 0        i2c_dev_num++;    if (i2c_dev_num >=  I2C_DEV_MAX) {	EPRINTF(("I2C_config: exceed max no. of devices!\n"));        return(-1);    }#endif    /* 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;      /* 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, w_addr);          /* word address */	}        i2c_writebyte(cptr, data);            /* data */        i2c_stop(cptr);                     /* stop condition */#ifndef CHEATq        // wait_timer(cptr->tWR);          /* write cycle time */#endif        if (!timeout)            return(0);    }        return(-1); /* timeout without acknowledge after several attempts */}     /****************************************************  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;     /* 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, 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 */}/****************************************************  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) */	    }	}//       AUD_service();  // cf    }}/* * 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){    int tmp;    int ack_starttime;    int k = -1;        cptr->SCL_set(1);	/* SCL TRISTATE_EAUX18 */	    ack_starttime = mvd[riface_timer2]; /* ack start time */    while (1) {		// wait hi	if (cptr->SCL_sense()){		break; //return;  //	}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 */		    }	 }    }}/****************************************************  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);			/*1 SDA 1  */#ifndef CHEAT        // wait_timer(cptr->tLOW);		/* SCL low time */#endif        i2c_raise_scl(cptr);			/*2 SCL high */        // wait_timer((cptr->tR)+(cptr->tSU_STA));	/* SCL rise time + start condition setup time */        cptr->SDA_set(0);			/*3 SDA low */        // wait_timer((cptr->tF)+(cptr->tHD_STA));	/* SDA fall time + start condition hold time */        cptr->SCL_set(0);			/*4 SCL low */

⌨️ 快捷键说明

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