_RB_INLINE bool check_RX_done(int dev) { unsigned long nowtime; unsigned char statreg; for (nowtime=0; nowtime<100000L; nowtime++) //trick for speed; timer_nowtime() is time-consuming in some OS if (i2c_CheckRXRdy(dev) == true) goto RX_SUCCESS; nowtime = timer_nowtime(); while ((i2c_CheckRXRdy(dev) == false) && ((timer_nowtime() - nowtime) < I2C_TIMEOUT)); RX_SUCCESS: statreg = i2c_ReadStatREG(dev); //ugly code for speed:p i2c_ClearRXRdy(dev); if ((statreg & 0x08) != 0) //if (i2cmaster_CheckARLoss(dev) == true) { err_SetMsg(ERROR_I2CARLOSS, "arbitration loss for I2C bus"); i2cmaster_ClearARLoss(dev); return false; } if ((statreg & 0x01) == 0) //if (i2c_IsMaster(dev) == false) { err_SetMsg(ERROR_I2CFAIL, "I2C%d module isn't in Master Mode", dev); return false; } if ((statreg & 0x40) == 0) //if (i2c_CheckRXRdy(dev) == false) { err_SetMsg(ERROR_I2CFAIL, "I2C%d module doesn't respond", dev); return false; } return true; }
/******************** Slave Functions for Individual Module *****************/ RBAPI(unsigned) i2cslave_Listen(int dev) { unsigned char i2cstat; switch (I2C_action[dev]) { case I2CACT_IDLE: if (i2c_IsMaster(dev) == true) return I2CSLAVE_NOTHING; I2C_action[dev] = I2CACT_SLAVE; return I2CSLAVE_START; case I2CACT_SLAVE: i2cstat = i2c_ReadStatREG(dev); if ((i2cstat & I2CSTAT_RXRDY) != 0) { I2C_action[dev] = I2CACT_SLAVEREADREQ; return I2CSLAVE_READREQUEST; } if ((i2cstat & I2CSTAT_SLAVESTOPPED) != 0) { i2c_ClearSTAT(dev, I2CSTAT_ALL); I2C_action[dev] = I2CACT_IDLE; return I2CSLAVE_END; } if ((i2cstat & I2CSTAT_SLAVEWREQ) != 0) { I2C_action[dev] = I2CACT_SLAVEWRITEREQ; return I2CSLAVE_WRITEREQUEST; } return I2CSLAVE_WAITING; case I2CACT_SLAVEWRITEREQ: case I2CACT_SLAVEREADREQ: err_SetMsg(ERROR_I2CWRONGUSAGE, "must deal with the salve read/write request"); break; case I2CACT_DISABLE: err_SetMsg(ERROR_I2CWRONGUSAGE, "must enable the I2C module first"); break; default: err_SetMsg(ERROR_I2CWRONGUSAGE, "can't use %s() when I2C master is working", __FUNCTION__); break; } return 0xffff; }
DMP_INLINE(bool) check_TX_done(int dev) { unsigned long nowtime; unsigned char statreg; for (nowtime=0; nowtime<100000L; nowtime++) //trick for speed; timer_NowTime() is time-consuming in some OS if (i2c_CheckTXDone(dev) == true) goto TX_SUCCESS; nowtime = timer_NowTime(); while ((i2c_CheckTXDone(dev) == false) && ((timer_NowTime() - nowtime) < I2C_TIMEOUT)); TX_SUCCESS: statreg = i2c_ReadStatREG(dev); //ugly code for speed:p i2c_ClearTXDone(dev); if ((statreg & 0x08) != 0) //if (i2cmaster_CheckARLoss(dev) == true) { err_print("arbitration loss for I2C bus"); i2cmaster_ClearARLoss(dev); } if ((statreg & 0x10) != 0) //if (i2cmaster_CheckAckErr(dev) == true) { err_print("receive no ACK after transmitting"); i2cmaster_ClearAckErr(dev); } if ((statreg & (0x10 + 0x08)) != 0) return false; if ((statreg & 0x01) == 0) //if (i2c_IsMaster(dev) == false) { err_print("I2C%d module isn't in Master Mode", dev); return false; } if ((statreg & 0x20) == 0) //if (i2c_CheckTXDone(dev) == false) { err_print("I2C%d module doesn't respond", dev); return false; } return true; }