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

📄 i2c1.c

📁 嵌入式linux的bsp
💻 C
📖 第 1 页 / 共 3 页
字号:
    if ( buffer_ptr == 0 || length == 0 )    {      return I2CERROR;    }#ifdef I2CDBG0	PRINT( "%s(%d): I2C_get\n", __FILE__, __LINE__ );#endif    RcvByte = 0;    ByteToRcv = length;    RcvBuf = buffer_ptr;    RcvBufFulStop = stop_flag;    XmitByte = 0;    ByteToXmit = 0;    XmitBuf = 0;    /* we are the master, start the transaction */    return I2C_Start( eumbbar, rcv_from, RCV, is_cnt );}#if 0 /* turn off dead code *//********************************************************* * function: I2C_write * * description: * Send a buffer of data to the requiring master. * If stop_flag is set, after the whole buffer is sent, * generate a STOP signal provided that the requiring * receiver doesn't signal the STOP in the middle. * I2C is the slave performing transmitting. * * 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 ) ){#ifdef I2CDBG0	PRINT( "%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__ );#endif    I2C_STAT 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					                           */{#ifdef I2CDBG0	PRINT( "%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__, __LINE__ ,      slave_addr,mode,is_cnt);#endif	unsigned int tmp = 0;    I2C_STAT stat;    I2C_CTRL 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 ){#ifdef I2CDBG0	PRINT( "%s(%d): I2C_Stop enter\n", __FILE__, __LINE__ );#endif    I2C_CTRL 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 *

⌨️ 快捷键说明

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