AVR Multi-master Bus Arbitration

A project log for Intelligent Shields

A system to build intelligent shields, for use with Arduino, Raspberry Pi or directly connected to a computer.

Mattias WingstedtMattias Wingstedt 08/21/2014 at 01:350 Comments

One of the design issues of the intelligent shield bus is how to send interrupts from a shield. I like event based programming and think that shields should be able to create events, they should not need to be polled.

Adding interrupt signals to the bus is not a good solution. It would be much nicer if we could just use the I2C bus itself. And we can. By using the Multi-master mode. In Multi-master mode several nodes can write to the bus at the same time, and use Bus Arbitration to find out that this is happening and determine which node gets to keep writing to the bus.

It may complicate our terminology when shields, as well as the CPU board, can be bus masters. But we really need the functionality.

One complication, the node that lost the bus arbitration may actually be the intended destination for the transfer that won. So a node may have to interrupt writing to the bus and instead start reading from it. Fortunately at least some AVR processors has support for this. And it turns out that the default Arduino Wire library actually seems to implement this support. If the AVR is in Master Transmitter or Master Receive mode, loses arbitration, finds out that the address on the bus is its own slave address (or the general call address) it will actually move to Slave Receive or Slave Transmitter automatically. Nice.

However one thing the Wire library does is that it considers a lost bus arbitration to be an error condition, and aborts writing to the bus. This is not what we want. Instead we should instruct the AVR to wait for a STOP condition and then retry sending data. Unless we are addressed, then we need to handle the incoming call before we try to write to the bus.

Bus arbitration is not an error, but a normal condition of having multiple masters on the bus.