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

📄 i2c1.c

📁 嵌入式linux的bsp
💻 C
📖 第 1 页 / 共 3 页
字号:
 ***************************************************/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 );	      }	      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				              */{#ifdef I2CDBG0	PRINT( "%s(%d): I2C_Init enter\n", __FILE__, __LINE__ );#endif    I2C_CTRL ctrl = I2C_Get_Ctrl( eumbbar );    unsigned int tmp;    /* 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 = load_runtime_reg( eumbbar, I2CSR );#ifdef I2CDBG0	PRINT( "%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp );#endif    I2C_STAT stat;    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 ){#ifdef I2CDBG0	PRINT( "%s(%d): I2C_ISR\n", __FILE__, __LINE__ );#endif    I2C_STAT stat = I2C_Get_Stat( eumbbar );    I2C_CTRL 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 );}

⌨️ 快捷键说明

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