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

📄 i2c1.c

📁 ppcboot2.0 华恒光盘里带的BOOTLOADER
💻 C
📖 第 1 页 / 共 3 页
字号:
 * * Note: this is slave xmit API. * *       due to the current Kahlua design, slave transmitter *       shall not signal STOP since there is no way *       for master to detect it, causing I2C bus hung. * *       For the above reason, the stop_flag is always *       set, i.e., 0. * *       programmer shall use the timer on Kahlua to *       control the interval of data byte at the *       master side. *******************************************************/static I2CStatus I2C_write (unsigned int eumbbar, unsigned char *buffer_ptr,	/* pointer of data to be sent */		unsigned int length,	/* number of byte of in the buffer */		unsigned int stop_flag){					/* 1 - signal STOP when buffer is empty					 * 0 - no STOP signal when buffer is empty					 */	if (buffer_ptr == 0 || length == 0) {		return I2CERROR;	}	XmitByte = 0;	ByteToXmit = length;	XmitBuf = buffer_ptr;	XmitBufEmptyStop = 0;	/* in order to avoid bus hung, ignored the user's stop_flag */	RcvByte = 0;	ByteToRcv = 0;	RcvBuf = 0;	/* we are the slave, just wait for being called, or pull */	/* I2C_Timer_Event( eumbbar ); */}/****************************************************** * function: I2C_read * * description: * Receive a buffer of data from the sending master. * If stop_flag is set, when the buffer is full and the * sender does not signal STOP, generate a STOP signal. * I2C is the slave performing receiving. * * note: this is slave receive API ****************************************************/static I2CStatus I2C_read (unsigned int eumbbar, unsigned char *buffer_ptr,	/* pointer of receiving buffer */		   unsigned int length,	/* length of the receiving buffer */		   unsigned int stop_flag){					/* 1 - signal STOP when buffer is full					 * 0 - no STOP signal when buffer is full					 */	if (buffer_ptr == 0 || length == 0) {		return I2CERROR;	}	RcvByte = 0;	ByteToRcv = length;	RcvBuf = buffer_ptr;	RcvBufFulStop = stop_flag;	XmitByte = 0;	ByteToXmit = 0;	XmitBuf = 0;	/* wait for master to call us, or poll */	/* I2C_Timer_Event( eumbbar ); */}#endif	/* turn off dead code *//********************************************************* * function: I2c_Timer_Event * * description: * if interrupt is not used, this is the timer event handler. * After each fixed time interval, this function can be called * to check the I2C status and call appropriate function to * handle the status event. ********************************************************/static I2CStatus I2C_Timer_Event (unsigned int eumbbar,				  I2CStatus (*handler) (unsigned int)){	I2C_STAT stat;#ifdef I2CDBG0	PRINT ("%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__);#endif	stat = I2C_Get_Stat (eumbbar);	if (stat.mif == 1) {		if (handler == 0) {			return I2C_ISR (eumbbar);		} else {			return (*handler) (eumbbar);		}	}	return I2CNOEVENT;}/****************** Device I/O function *****************//****************************************************** * function: I2C_Start * * description: Generate a START signal in the desired mode. *              I2C is the master. * *              Return I2CSUCCESS if no error. * * note: ****************************************************/static I2CStatus I2C_Start (unsigned int eumbbar, unsigned char slave_addr,	/* address of the receiver */			I2C_MODE mode,	/* XMIT(1) - put (write)					 * RCV(0)  - get (read)					 */			unsigned int is_cnt){					/* 1 - this is a restart, don't check MBB					 * 0 - this is a new start					 */	unsigned int tmp = 0;	I2C_STAT stat;	I2C_CTRL ctrl;#ifdef I2CDBG0	PRINT ("%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__,		   __LINE__, slave_addr, mode, is_cnt);#endif	ctrl = I2C_Get_Ctrl (eumbbar);	/* first make sure I2C has been initialized */	if (ctrl.men == 0) {		return I2CERROR;	}	/* next make sure bus is idle */	stat = I2C_Get_Stat (eumbbar);	if (is_cnt == 0 && stat.mbb == 1) {		/* sorry, we lost */		return I2CBUSBUSY;	} else if (is_cnt == 1 && stat.mif == 1 && stat.mal == 0) {		/* sorry, we lost the bus */		return I2CALOSS;	}	/* OK, I2C is enabled and we have the bus */	/* prepare to write the slave address */	ctrl.msta = 1;	ctrl.mtx = 1;	ctrl.txak = 0;	ctrl.rsta = is_cnt;		/* set the repeat start bit */	I2C_Set_Ctrl (eumbbar, ctrl);	/* write the slave address and xmit/rcv mode bit */	tmp = load_runtime_reg (eumbbar, I2CDR);	tmp = (tmp & 0xffffff00) | 	      ((slave_addr & 0x007f) << 1) | 	      (mode == XMIT ? 0x0 : 0x1);	store_runtime_reg (eumbbar, I2CDR, tmp);	if (mode == RCV) {		MasterRcvAddress = 1;	} else {		MasterRcvAddress = 0;	}#ifdef I2CDBG0	PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__);#endif	/* wait for the interrupt or poll  */	return I2CSUCCESS;}/*********************************************************** * function: I2c_Stop * * description: Generate a STOP signal to terminate the master *              transaction. *              return I2CSUCCESS * **********************************************************/static I2CStatus I2C_Stop (unsigned int eumbbar){	I2C_CTRL ctrl;#ifdef I2CDBG0	PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__);#endif	ctrl = I2C_Get_Ctrl (eumbbar);	ctrl.msta = 0;	I2C_Set_Ctrl (eumbbar, ctrl);#ifdef I2CDBG0	PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__);#endif	return I2CSUCCESS;}/**************************************************** * function: I2C_Master_Xmit * * description: Master sends one byte of data to *              slave target * *              return I2CSUCCESS if the byte transmitted. *              Otherwise no-zero * * Note: condition must meet when this function is called: *       I2CSR(MIF) == 1 && I2CSR(MCF)  == 1  && I2CSR(RXAK) == 0 *       I2CCR(MSTA) == 1  && I2CCR(MTX) == 1 * ***************************************************/static I2CStatus I2C_Master_Xmit (unsigned int eumbbar){	unsigned int val;	if (ByteToXmit > 0) {		if (ByteToXmit == XmitByte) {			/* all xmitted */			ByteToXmit = 0;			if (XmitBufEmptyStop == 1) {				I2C_Stop (eumbbar);			}			return I2CBUFFEMPTY;		}#ifdef I2CDBG0		PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,			   *(XmitBuf + XmitByte));#endif		val = *(XmitBuf + XmitByte);		val &= 0x000000ff;		store_runtime_reg (eumbbar, I2CDR, val);		XmitByte++;		return I2CSUCCESS;	}	return I2CBUFFEMPTY;}/*********************************************** * function: I2C_Master_Rcv * * description: master reads one byte data *              from slave source * *              return I2CSUCCESS if no error * * Note: condition must meet when this function is called: *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && *       I2CCR(MSTA) == 1 && I2CCR(MTX) == 0 * ***********************************************/static I2CStatus I2C_Master_Rcv (unsigned int eumbbar){	I2C_CTRL ctrl;	unsigned int val;	if (ByteToRcv > 0) {		if (ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1) {			/* master requests more than or equal to 2 bytes			 * we are reading 2nd to last byte			 */			/* we need to set I2CCR(TXAK) to generate a STOP */			ctrl = I2C_Get_Ctrl (eumbbar);			ctrl.txak = 1;			I2C_Set_Ctrl (eumbbar, ctrl);			/* Kahlua will automatically generate a STOP			 * next time a transaction happens			 */			/* note: the case of master requesting one byte is			 *       handled in I2C_ISR			 */		}		/* generat a STOP before reading the last byte */		if (RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1) {			I2C_Stop (eumbbar);		}		val = load_runtime_reg (eumbbar, I2CDR);		*(RcvBuf + RcvByte) = val & 0xFF;#ifdef I2CDBG0		PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,			   *(RcvBuf + RcvByte));#endif		RcvByte++;		if (ByteToRcv == RcvByte) {			ByteToRcv = 0;			return I2CBUFFFULL;		}		return I2CSUCCESS;	}	return I2CBUFFFULL;}/**************************************************** * function: I2C_Slave_Xmit * * description: Slave sends one byte of data to *              requesting destination * *        return SUCCESS if the byte transmitted. Otherwise *        No-zero * * Note: condition must meet when this function is called: *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&  I2CSR(RXAK) = 0 *       I2CCR(MSTA) == 0  && I2CCR(MTX) == 1 * ***************************************************/static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar){	unsigned int val;	if (ByteToXmit > 0) {		if (ByteToXmit == XmitByte) {			/* no more data to send */			ByteToXmit = 0;			/*                         * do not toggle I2CCR(MTX). Doing so will                         * cause bus-hung since current Kahlua design                         * does not give master a way to detect slave                         * stop. It is always a good idea for master                         * to use timer to prevent the long long                         * delays			 */			return I2CBUFFEMPTY;		}#ifdef I2CDBG		PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,			   *(XmitBuf + XmitByte));#endif		val = *(XmitBuf + XmitByte);		val &= 0x000000ff;		store_runtime_reg (eumbbar, I2CDR, val);		XmitByte++;		return I2CSUCCESS;	}	return I2CBUFFEMPTY;}/*********************************************** * function: I2C_Slave_Rcv * * description: slave reads one byte data *              from master source * *              return I2CSUCCESS if no error otherwise non-zero * * Note: condition must meet when this function is called: *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && *       I2CCR(MSTA) == 0 && I2CCR(MTX)  = 0 * ***********************************************/static I2CStatus I2C_Slave_Rcv (unsigned int eumbbar){	unsigned int val;	I2C_CTRL ctrl;	if (ByteToRcv > 0) {		val = load_runtime_reg (eumbbar, I2CDR);		*(RcvBuf + RcvByte) = val & 0xff;#ifdef I2CDBG		PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,			   *(RcvBuf + RcvByte));#endif		RcvByte++;		if (ByteToRcv == RcvByte) {			if (RcvBufFulStop == 1) {				/* all done */				ctrl = I2C_Get_Ctrl (eumbbar);				ctrl.txak = 1;				I2C_Set_Ctrl (eumbbar, ctrl);			}

⌨️ 快捷键说明

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