RBAPI(bool) i2cmaster_WriteLast(int dev, unsigned char val) { bool result = true; if (i2cmaster_Write(dev, val) == false) return false; else I2C_action[dev] = I2CACT_IDLE; // case of I2C RESTART after write if (I2C_rsInfo[dev].restart == true) { I2C_rsInfo[dev].restart = false; if (I2C_swMode[dev] != I2CSW_DISABLE) result = i2csw_Start(dev, I2C_rsInfo[dev].addr, I2C_rsInfo[dev].rwbit, true); else result = i2cmaster_Start1(dev, I2C_rsInfo[dev].addr, I2C_rsInfo[dev].rwbit); if (result == true) { I2C_action[dev] = (I2C_rsInfo[dev].rwbit == I2C_WRITE)? I2CACT_MASTERWRITE : I2CACT_MASTERREAD; I2C_count[dev] = I2C_rsInfo[dev].count; } return result; } // case of I2C STOP after write if (I2C_swMode[dev] != I2CSW_DISABLE) i2csw_Stop(dev); else { i2cmaster_SetStopBit(dev); result = check_STOP_done(dev); } return result; }
RBAPI(unsigned) i2cmaster_ReadLast(int dev) { unsigned val; switch (I2C_action[dev]) { case I2CACT_MASTERREAD: if (I2C_swMode[dev] == I2CSW_DISABLE) { if (I2C_rsInfo[dev].restart == true) { i2cmaster_WriteAddrREG(dev, I2C_rsInfo[dev].addr, I2C_rsInfo[dev].rwbit); delay_us(150L); //Remarks: must delay here due to DX's I2C H/W bug } else i2cmaster_SetStopBit(dev); } break; case I2CACT_MASTERHASREAD: err_SetMsg(ERROR_I2CWRONGUSAGE, "set Second-Last-Read before calling %s()", __FUNCTION__); return 0xffff; case I2CACT_MASTERLASTREAD: I2C_action[dev] = I2CACT_MASTERHASREAD; // for calling i2cmaster_Read1() again to get the last byte break; } val = (I2C_swMode[dev] != I2CSW_DISABLE)? i2csw_Read(dev, true) : i2cmaster_Read1(dev, false); I2C_action[dev] = I2CACT_IDLE; if (val == 0xffff) return 0xffff; if (I2C_rsInfo[dev].restart == true) { I2C_rsInfo[dev].restart = false; if (I2C_swMode[dev] != I2CSW_DISABLE) { if (i2csw_Start(dev, I2C_rsInfo[dev].addr, I2C_rsInfo[dev].rwbit, true) == false) return 0xffff; } else { if (check_TX_done(dev) == false) return 0xffff; } I2C_action[dev] = (I2C_rsInfo[dev].rwbit == I2C_WRITE)? I2CACT_MASTERWRITE : I2CACT_MASTERREAD; I2C_count[dev] = I2C_rsInfo[dev].count; } else { if (I2C_swMode[dev] != I2CSW_DISABLE) i2csw_Stop(dev); else { if (check_STOP_done(dev) == false) return 0xffff; } }//end if I2C_restart... return val; }
RBAPI(bool) i2cmaster_WriteLast(int dev, unsigned char val) { if (i2cmaster_Write(dev, val) == false) return false; else I2C_action[dev] = I2CACT_IDLE; if (I2C_rsInfo[dev].restart == true) { I2C_rsInfo[dev].restart = false; if (i2cmaster_Start1(dev, I2C_rsInfo[dev].addr, I2C_rsInfo[dev].rwbit) == false) return false; I2C_count = I2C_rsInfo[dev].count; return true; } i2cmaster_SetStopBit(dev); return check_STOP_done(dev); }
//Remarks: the following "Read" functions are odd due to Vortex86DX's poor I2C design RBAPI(unsigned) i2cmaster_Read1(int dev, bool secondlast) { switch (I2C_action[dev]) { case I2CACT_MASTERREAD: if (I2C_swMode[dev] == I2CSW_DISABLE) i2c_ReadDataREG(dev); // dummy read to trigger the I2C module for reading a byte I2C_action[dev] = I2CACT_MASTERHASREAD; break; case I2CACT_MASTERHASREAD: break; case I2CACT_MASTERLASTREAD: err_SetMsg(ERROR_I2CWRONGUSAGE, "call i2cmaster_ReadLast() to read the last byte"); return 0xffff; default: err_SetMsg(ERROR_I2CWRONGUSAGE, "must start a correct transaction before reading data"); return 0xffff; } if (I2C_swMode[dev] == I2CSW_DISABLE) { if (check_RX_done(dev) == false) { I2C_action[dev] = I2CACT_IDLE; return 0xffff; } if (secondlast == true) { if (I2C_rsInfo[dev].restart == true) { i2cmaster_WriteAddrREG(dev, I2C_rsInfo[dev].addr, I2C_rsInfo[dev].rwbit); delay_us(150L); //Remarks: must delay here due to DX's I2C H/W bug } else i2cmaster_SetStopBit(dev); } } //end if (I2C_swMode[dev] ... if (secondlast == true) I2C_action[dev] = I2CACT_MASTERLASTREAD; if (I2C_swMode[dev] != I2CSW_DISABLE) return i2csw_Read(dev, false); else return (unsigned)i2c_ReadDataREG(dev); //Remarks: this read will trigger I2C module to read the next byte }
RBAPI(unsigned) i2cmaster_ReadLast(int dev) { unsigned val; switch (I2C_action[dev]) { case I2CACT_MASTERREAD: if (I2C_rsInfo[dev].restart == true) { i2cmaster_WriteAddrREG(dev, I2C_rsInfo[dev].addr, I2C_rsInfo[dev].rwbit); delay_ms(1); //Remarks: must delay here due to DX's I2C H/W bug } else i2cmaster_SetStopBit(dev); break; case I2CACT_MASTERHASREAD: err_SetMsg(ERROR_I2CWRONGUSAGE, "set Second-Last-Read before calling %s()", __FUNCTION__); return 0xffff; case I2CACT_MASTERLASTREAD: I2C_action[dev] = I2CACT_MASTERHASREAD; break; } if ((val = i2cmaster_Read1(dev, false)) == 0xffff) return 0xffff; else I2C_action[dev] = I2CACT_IDLE; if (I2C_rsInfo[dev].restart == true) { I2C_rsInfo[dev].restart = false; if (check_TX_done(dev) == false) return 0xffff; I2C_count = I2C_rsInfo[dev].count; I2C_action[dev] = (I2C_rsInfo[dev].rwbit == I2C_WRITE)? I2CACT_MASTERWRITE : I2CACT_MASTERREAD; } else { if (check_STOP_done(dev) == false) return 0xffff; }//end if I2C_restart... return val; }