Closed dragoncoder047 closed 1 year ago
Does this help to shed any light on the issue? it sounded like you ha misconceptions about how I2C and the wire API works and what the different parts know and tell eachother at various points in the process - if your onRequest only writes one byte, you'd get 1 byte of data and 3 255's
In I2C, the way a read works is that the master addresses the slave with the read bit set and that triggers the callback, during the callback you write all the data that the master might want (you have no idea how much it will read, it doesn't tell you) within the onRequest() handler on the slave
So my suspicion was correct. I fixed it to send all of the registers until the register pointer ran off the end, and it works now.
It's a shame that I can't have the register pointer automatically wrap at the end, but then again, I don't really need it to wrap.
I have an ATtiny85, and it's set up as an I2C slave on pins PB0 and PB2 using the built-in USI-based I2C implementation.
The I2C based code implements a typical register-based interface:
The onReceive() code works fine and I am able to write one register and write multiple registers successfully.
However, when I try to read more than one byte at once (i.e.
Wire.requestFrom(XXX, 4)
on the master side) only the first byte sends properly and the rest come back as just a bunch of useless 255's.In case it's relevant, there are no other interrupts on the ATtiny85 that could be interfering the USI interrupt.
The other problem I see might be that the onRequest() handler is only called once per transaction, not once per byte as I assumed it is, and so it only ever gets 1 byte in the send buffer. If that is the case, how do I know how many bytes the master wants in advance and/or flush the buffer at the end of the transaction?
I am also using an ESP32 as the I2C master, so if you know of any bugs in the ESP32's I2C implementation (particularly w.r.t. clock stretching) please let me know.