Skip to content

Wire Slave: arbitrary user code is called from ISR #342

Open
@greyltc

Description

@greyltc

When a user is using the Wire library in slave mode, they generally need to register a function to handle requests for data from the master. They write some function, which must contain Wire.write and register it like this: Wire.onRequest(someFunction);.

The issue here is that someFunction gets called (via twi_onSlaveTransmit) right in the slave's interrupt service routine:

twi_onSlaveTransmit();

First of all, the documentation for Wire.onRequest is truly tragic. It doesn't even tell the user they must make a call to Wire.write or else the wire library will decide for them to send 0x00 to the master, and it doesn't warn the user that they're writing code for inside an ISR.

Secondly, this architecture raises all kinds of potential usability issues. I think quite often a slave will need to do something much more complicated to answer a master's request than what should/can be done in an ISR. As I understand the code (please someone correct me if I'm wrong), it's impossible to answer the master outside of the call from the ISR. What if the slave needs the delay() function in forming its answer for the master? Impossible. What if the slave needs to fetch an answer for the master over SPI? Maybe that's possible, but it sure seems like a terrible idea to do that from inside an ISR.

I noticed a stub:

void TwoWire::flush(void)
{
// XXX: to be implemented.
}

Maybe the point of that was to help solve this problem?

Would you consider accepting a PR I might make so that a slave can form an answer to a master outside of the ISR?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions