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

📄 i2c1.c

📁 ppcboot2.0 华恒光盘里带的BOOTLOADER
💻 C
📖 第 1 页 / 共 3 页
字号:
			ByteToRcv = 0;			return I2CBUFFFULL;		}		return I2CSUCCESS;	}	return I2CBUFFFULL;}/****************** Device Control Function *************//********************************************************* * function: I2C_Init * * description: Initialize I2C unit with desired frequency divider, *              master's listening address, with interrupt enabled *              or disabled. * * note: ********************************************************/static I2CStatus I2C_Init (unsigned int eumbbar, unsigned char fdr,	/* frequency divider */		   unsigned char slave_addr,	/* driver's address used for receiving */		   unsigned int en_int){						/* 1 - enable I2C interrupt						 * 0 - disable I2C interrup						 */	I2C_CTRL ctrl;	unsigned int tmp;#ifdef I2CDBG0	PRINT ("%s(%d): I2C_Init enter\n", __FILE__, __LINE__);#endif	ctrl = I2C_Get_Ctrl (eumbbar);	/* disable the I2C module before we change everything */	ctrl.men = 0;	I2C_Set_Ctrl (eumbbar, ctrl);	/* set the frequency diver */	tmp = load_runtime_reg (eumbbar, I2CFDR);	tmp = (tmp & 0xffffffc0) | (fdr & 0x3f);	store_runtime_reg (eumbbar, I2CFDR, tmp);	/* Set our listening (slave) address */	tmp = load_runtime_reg (eumbbar, I2CADR);	tmp = (tmp & 0xffffff01) | ((slave_addr & 0x7f) << 1);	store_runtime_reg (eumbbar, I2CADR, tmp);	/* enable I2C with desired interrupt setting */	ctrl.men = 1;	ctrl.mien = en_int & 0x1;	I2C_Set_Ctrl (eumbbar, ctrl);#ifdef I2CDBG0	PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__);#endif	return I2CSUCCESS;}/***************************************** * function I2c_Get_Stat * * description: Query I2C Status, i.e., read I2CSR * ****************************************/static I2C_STAT I2C_Get_Stat (unsigned int eumbbar){	unsigned int temp;	I2C_STAT stat;	temp = load_runtime_reg (eumbbar, I2CSR);#ifdef I2CDBG0	PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp);#endif	stat.rsrv0 = (temp & 0xffffff00) >> 8;	stat.mcf   = (temp & 0x00000080) >> 7;	stat.maas  = (temp & 0x00000040) >> 6;	stat.mbb   = (temp & 0x00000020) >> 5;	stat.mal   = (temp & 0x00000010) >> 4;	stat.rsrv1 = (temp & 0x00000008) >> 3;	stat.srw   = (temp & 0x00000004) >> 2;	stat.mif   = (temp & 0x00000002) >> 1;	stat.rxak  = (temp & 0x00000001);	return stat;}/********************************************* * function: I2c_Set_Ctrl * * description: Change I2C Control bits, *              i.e., write to I2CCR * ********************************************/static void I2C_Set_Ctrl (unsigned int eumbbar, I2C_CTRL ctrl){						/* new control value */	unsigned int temp = load_runtime_reg (eumbbar, I2CCR);	temp &= 0xffffff03;	temp |= ((ctrl.men  & 0x1) << 7);	temp |= ((ctrl.mien & 0x1) << 6);	temp |= ((ctrl.msta & 0x1) << 5);	temp |= ((ctrl.mtx  & 0x1) << 4);	temp |= ((ctrl.txak & 0x1) << 3);	temp |= ((ctrl.rsta & 0x1) << 2);#ifdef I2CDBG0	PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp);#endif	store_runtime_reg (eumbbar, I2CCR, temp);}/***************************************** * function: I2C_Get_Ctrl * * description: Query I2C Control bits, *              i.e., read I2CCR *****************************************/static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar){	union {		I2C_CTRL ctrl;		unsigned int temp;	} s;	s.temp = load_runtime_reg (eumbbar, I2CCR);#ifdef I2CDBG0	PRINT ("%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp);#endif	return s.ctrl;}/**************************************** * function: I2C_Slave_Addr * * description: Process slave address phase. *              return I2CSUCCESS if no error * * note: Precondition for calling this function: *       I2CSR(MIF) == 1 && *       I2CSR(MAAS) == 1 ****************************************/static I2CStatus I2C_Slave_Addr (unsigned int eumbbar){	I2C_STAT stat = I2C_Get_Stat (eumbbar);	I2C_CTRL ctrl = I2C_Get_Ctrl (eumbbar);	if (stat.srw == 1) {		/* we are asked to xmit */		ctrl.mtx = 1;		I2C_Set_Ctrl (eumbbar, ctrl);	/* set MTX */		return I2C_Slave_Xmit (eumbbar);	}	/* we are asked to receive data */	ctrl.mtx = 0;	I2C_Set_Ctrl (eumbbar, ctrl);	(void) load_runtime_reg (eumbbar, I2CDR);	/* do a fake read to start */	return I2CADDRESS;}/*********************************************** * function: I2C_ISR * * description: I2C Interrupt service routine * * note: Precondition: *      I2CSR(MIF) == 1 **********************************************/static I2CStatus I2C_ISR (unsigned int eumbbar){	I2C_STAT stat;	I2C_CTRL ctrl;#ifdef I2CDBG0	PRINT ("%s(%d): I2C_ISR\n", __FILE__, __LINE__);#endif	stat = I2C_Get_Stat (eumbbar);	ctrl = I2C_Get_Ctrl (eumbbar);	/* clear MIF */	stat.mif = 0;	/* Now let see what kind of event this is */	if (stat.mcf == 1) {		/* transfer compete */		/* clear the MIF bit */		I2C_Set_Stat (eumbbar, stat);		if (ctrl.msta == 1) {			/* master */			if (ctrl.mtx == 1) {				/* check if this is the address phase for master receive */				if (MasterRcvAddress == 1) {					/* Yes, it is the address phase of master receive */					ctrl.mtx = 0;					/* now check how much we want to receive */					if (ByteToRcv == 1 && RcvBufFulStop == 1) {						ctrl.txak = 1;					}					I2C_Set_Ctrl (eumbbar, ctrl);					(void) load_runtime_reg (eumbbar, I2CDR);	/* fake read first */					MasterRcvAddress = 0;					return I2CADDRESS;				}				/* master xmit */				if (stat.rxak == 0) {					/* slave has acknowledged */					return I2C_Master_Xmit (eumbbar);				}				/* slave has not acknowledged yet, generate a STOP */				if (XmitBufEmptyStop == 1) {					ctrl.msta = 0;					I2C_Set_Ctrl (eumbbar, ctrl);				}				return I2CSUCCESS;			}			/* master receive */			return I2C_Master_Rcv (eumbbar);		}		/* slave */		if (ctrl.mtx == 1) {			/* slave xmit */			if (stat.rxak == 0) {				/* master has acknowledged */				return I2C_Slave_Xmit (eumbbar);			}			/* master has not acknowledged, wait for STOP */			/* do nothing for preventing bus from hung */			return I2CSUCCESS;		}		/* slave rcv */		return I2C_Slave_Rcv (eumbbar);	} else if (stat.maas == 1) {		/* received a call from master */		/* clear the MIF bit */		I2C_Set_Stat (eumbbar, stat);		/* master is calling us, process the address phase */		return I2C_Slave_Addr (eumbbar);	} else {		/* has to be arbitration lost */		stat.mal = 0;		I2C_Set_Stat (eumbbar, stat);		ctrl.msta = 0;			/* return to receive mode */		I2C_Set_Ctrl (eumbbar, ctrl);	}	return I2CSUCCESS;}/****************************************************** * function: I2C_Set_Stat * * description: modify the I2CSR * *****************************************************/static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat){	union {		unsigned int val;		I2C_STAT stat;	} s_tmp;	union {		unsigned int val;		I2C_STAT stat;	} s;	s.val = load_runtime_reg (eumbbar, I2CSR);	s.val &= 0xffffff08;	s_tmp.stat = stat;	s.val |= (s_tmp.val & 0xf7);#ifdef I2CDBG0	PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val);#endif	store_runtime_reg (eumbbar, I2CSR, s.val);}/****************************************************** * The following are routines to glue the rest of * PPCBoot to the Sandpoint I2C driver. *****************************************************/void i2c_init (int speed, int slaveadd){#ifdef DEBUG	I2C_Initialize (0x7f, 0, (void *) printf);#else	I2C_Initialize (0x7f, 0, 0);#endif}int i2c_probe (uchar chip){	int tmp;	/*	 * Try to read the first location of the chip.  The underlying	 * driver doesn't appear to support sending just the chip address	 * and looking for an <ACK> back.	 */	udelay(10000);	return i2c_read (chip, 0, 1, (char *)&tmp, 1);}int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len){	I2CStatus status;	uchar xaddr[4];	if (alen > 0) {		xaddr[0] = (addr >> 24) & 0xFF;		xaddr[1] = (addr >> 16) & 0xFF;		xaddr[2] = (addr >> 8) & 0xFF;		xaddr[3] = addr & 0xFF;		status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen,					&xaddr[4 - alen], I2C_NO_STOP, 1,					I2C_NO_RESTART);		if (status != I2C_SUCCESS) {			PRINT ("i2c_read: can't send data address for read\n");			return 1;		}	}	/* The data transfer will be a continuation. */	status = I2C_do_buffer (0, I2C_MASTER_RCV, chip, len,				buffer, I2C_STOP, 1, (alen > 0 ? I2C_RESTART :				I2C_NO_RESTART));	if (status != I2C_SUCCESS) {		PRINT ("i2c_read: can't perform data transfer\n");		return 1;	}	return 0;}int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len){	I2CStatus status;	unsigned char dummy_buffer[I2C_RXTX_LEN + 2];	int i;	dummy_buffer[0] = addr & 0xFF;	if (alen == 2)		dummy_buffer[1] = (addr >> 8) & 0xFF;	for (i = 0; i < len; i++)		dummy_buffer[i + alen] = buffer[i];	status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen + len,				dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART);#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS	udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);#endif	if (status != I2C_SUCCESS) {		PRINT ("i2c_write: can't perform data transfer\n");		return 1;	}	return 0;}uchar i2c_reg_read (uchar i2c_addr, uchar reg){	char buf[1];	i2c_init (0, 0);	i2c_read (i2c_addr, reg, 1, buf, 1);	return (buf[0]);}void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val){	i2c_init (0, 0);	i2c_write (i2c_addr, reg, 1, &val, 1);}#endif	/* CONFIG_HARD_I2C */

⌨️ 快捷键说明

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