📄 i2c1.c
字号:
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 + -