rambo / TinyWire

My modifications to TinyWire Arduino libs
284 stars 121 forks source link

Quick question on TinyWireS.onRequest(handler) #45

Closed apiffa closed 6 years ago

apiffa commented 6 years ago

Hi, Thanks for the work on this library. The registered handler is called when the Master invokes Wire.requestFrom(), so far so good. When that happens, which kind of interrupt does actually bring up the handler? What I want to know is that, as the main loop will be interrupted, and if I am processing a series of values to be transmitted in the meanwhile, between requests, in the main loop, what care should I take to be safe. Thanks, Alvaro.

rambo commented 6 years ago

As far as I recall it's the USI interrupt vector, so don't spend too much time there. See for example https://github.com/rambo/TinyWire/blob/rollback/TinyWireS/examples/attiny85_i2c_analog/attiny85_i2c_analog.ino

There the requestEvent handler just send the value of the current index and increments the index counter. receiveEvent also just sets some flags to be handled in the mainloop.

As for processing series of values, you could use double-buffering where you first process them in one array and then copy them to the array that acts as the I2C registers (or just switch the "active registry" pointer around as needed), though even this does not guarantee you would not switch the array the master is reading in the middle of the transaction, but at least the array itself is internally consistent. You could check time since last requestEvent before switching the array if the master is not constantly reading at full speed, or you could switch it af the receiveEvent since very common convention in I2C devices is to start with a write of register address and then re-start with the read:

START slave_write_addr register_addr START slave_read_addr READ STOP

And of course reading as many bytes as we think we need.

apiffa commented 6 years ago

Thank you very much, best regards