Ok, I managed to make a bit bang i2c which performs the special write+read command. And in the process, I figured out that I can just use what the datasheet calls "1 byte read mode" setting in register 0x11 which is compatible with vanilla i2c drivers.
For fun here's the bit bang code
static const bool ACK = 0;
static const bool NACK = 1;
static const bool WRITE = 0;
static const bool READ = 1;
class bbi2c
{
public:
bbi2c(byte scl_pin, byte sda_pin, long bitrate = 100000)
: scl(scl_pin), sda(sda_pin), freq(bitrate)
{ up(scl);
up(sda);
}
operator bool()
{ return good;
}
bbi2c & start(byte addr, byte rw)
{ good = true;
down(sda);
tick();
down(scl);
return send((addr<<1)|(rw&1));
}
bbi2c & finish()
{ down(sda);
up(scl);
up(sda);
return *this;
}
bbi2c & send(byte data)
{ if(!good) { return *this; }
for(byte i=0 ; i<8 ; i++)
{ writeBit((data<<i)&0x80);
}
good &= (readBit() == ACK);
return *this;
}
bbi2c & recv(byte * data, bool ack=true)
{ if(!good) { return *this; }
*data = 0;
for(byte i=0 ; i<8 ; i++)
{ *data |= readBit()<<(7-i);
}
writeBit(ack ? ACK : NACK);
return *this;
}
private:
const byte scl;
const byte sda;
const long freq;
bool good = true;
byte readBit()
{ up(sda);
tick();
up(scl);
tick();
byte bit = digitalRead(sda);
down(scl);
return bit;
}
void writeBit(byte bit)
{ setdata(bit);
tick();
up(scl);
tick();
down(scl);
}
void setdata(byte val)
{ if(val) { up(sda); }
else { down(sda); }
}
void down(byte pin)
{ digitalWrite(pin, 0);
pinMode(pin, OUTPUT);
}
void up(byte pin)
{ pinMode(pin, INPUT_PULLUP);
digitalWrite(pin, 1);
// stretch or RC rise
for(int i=1000 ; i && pin==scl && !digitalRead(pin) ; i--);
}
void tick()
{ delayMicroseconds(500000/freq);
}
};
bbi2c i2c(19, 18);
int addr = 53;
void setup()
{ Serial.begin(9600);
delay(100);
// TLE493D-A2B6
// parity, 2 byte read, no INT, master control mode
i2c.start(addr,WRITE).send(0x11).send(0x85).finish();
// no temp, adc on read, parity bit
i2c.start(addr,WRITE).send(0x11).send(0x85).finish();
}
void loop()
{ delay(5000);
// register 0, trigger adc
i2c.start(addr,READ).send(0x80);
for(int i=0 ; i<7 ; i++)
{ byte buff = 0;
i2c.recv(&buff);
Serial.printf("got %d 0x%x\n", i, buff);
}
Serial.printf("recv good %d\n", (bool)i2c.finish());
}