Well, this is sweet! To make a long story short, the Wire library supports multi master I2C buses without a problem; the only thing which needs to be improved on is the documentation on the Arduino site (side note: how do we request a change in the docs? I would be willing to write up correct documentation if someone else can post it on the site).
I broke down and looked at the code for the Wire library, and it turns out that the twi.c function 'twi_writeto' is called from Wire.endTransmission(). In twi_writeto, the comments state that it first attempts to become bus master, then sends the message. From this, I was able to gather that the Wire library documentation is misleading; while you can join the bus as Master without an address, you can also join as a slave. The reason it says Master can join w/o an address is that it makes no sense for a device which could ever be used as a slave to join without an address.
Anyway, with this new datum, I modified the sketch, calling Wire.begin(address) only once for each chip, and using Wire.beginTransmission / Wire.send / Wire.endTransmission whenever an event needed to be processed. Lo and behold, it works perfectly!
Below is my code, in case someone is interested in doing I2C / TWI multi master with arduinos (use the same code for both chips, but swap THIS_ADDRESS and OTHER_ADDRESS for the second chip):
/**
*
* Sample Multi Master I2C implementation. Sends a button state over I2C to another
* Arduino, which flashes an LED correspinding to button state.
*
* Connections: Arduino analog pins 4 and 5 are connected between the two Arduinos,
* with a 1k pullup resistor connected to each line. Connect a push button between
* digital pin 10 and ground, and an LED (with a resistor) to digital pin 9.
*
*/
#include <Wire.h>
#define LED 9
#define BUTTON 10
#define THIS_ADDRESS 0x8
#define OTHER_ADDRESS 0x9
boolean last_state = HIGH;
void setup() {
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
pinMode(BUTTON, INPUT);
digitalWrite(BUTTON, HIGH);
Wire.begin(THIS_ADDRESS);
Wire.onReceive(receiveEvent);
}
void loop() {
if (digitalRead(BUTTON) != last_state){
last_state = digitalRead(BUTTON);
Wire.beginTransmission(OTHER_ADDRESS);
Wire.send(last_state);
Wire.endTransmission();
}
}
void receiveEvent(int howMany){
while (Wire.available() > 0){
boolean b = Wire.receive();
Serial.print(b, DEC);
digitalWrite(LED, !b);
}
Serial.println();
}
Thanks to all who replied for helping me walk through this one.
Cheers