I have set up my photon as i2c slave, using Wire lib.
The slave has data : uint32_t registers, i.e 8 bytes, that the master wants to read.
In setup I register a callback for the Wire.onRequest(). The callback (which takes no parameters) writes
all 8 bytes using Wire.write(registers, 8).
The callback which is registered with onRequest does not accept parameters, so I guess I have to dump all register bytes in the write() call even if the master requests less.
On Raspberry pi 3 I use smbus python lib to read from my photon over i2c.
Everything works as expected if I read 8 bytes or less and specify register 0.
But suppose I want only to read the 4 bytes in reg 1:
read_i2c_block_data(slave_address, 0x1, 4).
In this case I get 4 bytes from register 0x0!
Does Wire lib support reading from other than register 0?
The Wire library is very low-level and only supports sending and receiving in master or slave mode.
If you want to implement a normal I2C-device like feature like multiple registers, you need to build that on top of the low-level read and write calls.
One example of doing this is this library, which supports register semantics on a Photon/P1/Electron in I2C slave mode.
I tried that and it behaves similar. Ignores the register byte. Always read from 0.
I can add that I saw one interesting thing in the sequence using my logic analyzer.
The smbus specification says read_block sequence should look like:
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] A [Data] A … A [Data] NA P
But smbus inserts an CLOSE condition after the Ack after the Comm byte:
S Addr Wr [A] Comm [A] CLOSE S Addr Rd [A] [Data] A [Data] A … A [Data] NA P
I’m not sure what this Close condition is exactly. Does it confuse the I2CSlaveRK or lower layers?
It’s likely that the I2CSlaveRK library is not compatible with your smbus library on the Pi. It’s only designed to work with the example I2C master code in the library.