this is a test:
ret = i2cWrite(i2c, dev, addr_buf, sizeof(addr_buf), false);
TEST_ASSERT_EQUAL_MESSAGE(0, ret, "write rd address");
ret = i2cRead(i2c, dev, buf, len, true);
TEST_ASSERT_EQUAL_MESSAGE(0, ret, "read data");
this is a code:
OPTIMIZE
int8_t i2cRead(I2C *dev, int16_t address, uint8_t *buffer, i2c_cnt_size count, bool stop) {
bool nack;
if (!i2cStart(dev)) {
return i2cFailure(dev, -1, "Read start");
}
if (!i2cWriteByte(dev, address|1, &nack)) {
return i2cFailure(dev, -2, "Read send addr");
}
if (nack) {
return i2cFailure(dev, -3, "Read addr nack");
}
return i2cReadMore(dev, buffer, count, stop);
}
OPTIMIZE
int8_t i2cWrite(I2C *dev, int16_t address, const uint8_t *buffer, i2c_cnt_size count, bool stop) {
bool nack;
// putstr("i2cWrite: count: "); putu(count); putstr("stop: "); putu(stop); putstr("dev: "); putu((uint32_t)dev); putstr("address: "); putu(address); putstr("\n");
if (!i2cStart(dev)) {
return i2cFailure(dev, -1, "Write start");
}
if (!i2cWriteByte(dev, address, &nack)) {
return i2cFailure(dev, -2, "Write send addr");
}
if (nack) {
return i2cFailure(dev, -3, count ? "Write addr nack" : NULL);
}
return i2cWriteMore(dev, buffer, count, stop);
}
Low Level:
bool i2cWriteByte(I2C* bus, uint8_t byte, bool* nack)
{
LOG_M();
(void) bus;
/* Send data to the previously addressed device */
TWDR = byte;
TWCR = _BV(TWINT) | _BV(TWEN);
/* Wait until transmission completed */
while (!(TWCR & _BV(TWINT))) {
if(TW_STATUS == TW_MT_ARB_LOST){
printf("I2C Arbitration lost\n");
return false;
}
}
static unsigned cnt, tmp;
while(TW_STATUS == TW_REP_START){ <----------------------------------- here is counter, and here must not be been TW_REP_START! , without this while() - i get error message from my test!
++cnt;
tmp = byte;
}
if((TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) && (TW_STATUS != TW_MT_DATA_ACK)) {
*nack = 1;
} else {
*nack = 0;
}
// *nack = !(TW_STATUS == TW_MT_SLA_ACK || TW_STATUS == TW_MT_DATA_ACK || TW_STATUS == TW_MR_SLA_ACK || TW_STATUS == TW_REP_START);
// *nack=0;
// if(byte == 0xa1) printf("s: 0x%02x, nack= %d \n", TW_STATUS, *nack);
if(cnt) printf("cnt: %d, tmp= %d \n", cnt, tmp);
printf("TWS: 0x%02x \n", TW_STATUS);
return true;
}
here i expteted TW_REP_START:
bool i2cStart(I2C* bus)
{
LOG_M();
(void) bus;
/* Send START condition */
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
/* Wait until transmission completed */
while (!(TWCR & _BV(TWINT)))
;
if ((TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
return false;
return true;
}
A full version you can see in attachment.
I add external eeprom (i2c_eeprom) to µC (run_avr) and call test with run_avr :run_avr -ff -m atmega1280 -f 8000000 sim_i2test.hex -v -v.