mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.8 KiB
82 lines
2.8 KiB
GPIO-based I2C Arbitration Using a Challenge & Response Mechanism |
|
================================================================= |
|
This uses GPIO lines and a challenge & response mechanism to arbitrate who is |
|
the master of an I2C bus in a multimaster situation. |
|
|
|
In many cases using GPIOs to arbitrate is not needed and a design can use |
|
the standard I2C multi-master rules. Using GPIOs is generally useful in |
|
the case where there is a device on the bus that has errata and/or bugs |
|
that makes standard multimaster mode not feasible. |
|
|
|
Note that this scheme works well enough but has some downsides: |
|
* It is nonstandard (not using standard I2C multimaster) |
|
* Having two masters on a bus in general makes it relatively hard to debug |
|
problems (hard to tell if i2c issues were caused by one master, another, or |
|
some device on the bus). |
|
|
|
|
|
Algorithm: |
|
|
|
All masters on the bus have a 'bus claim' line which is an output that the |
|
others can see. These are all active low with pull-ups enabled. We'll |
|
describe these lines as: |
|
|
|
- OUR_CLAIM: output from us signaling to other hosts that we want the bus |
|
- THEIR_CLAIMS: output from others signaling that they want the bus |
|
|
|
The basic algorithm is to assert your line when you want the bus, then make |
|
sure that the other side doesn't want it also. A detailed explanation is best |
|
done with an example. |
|
|
|
Let's say we want to claim the bus. We: |
|
1. Assert OUR_CLAIM. |
|
2. Waits a little bit for the other sides to notice (slew time, say 10 |
|
microseconds). |
|
3. Check THEIR_CLAIMS. If none are asserted then the we have the bus and we are |
|
done. |
|
4. Otherwise, wait for a few milliseconds and see if THEIR_CLAIMS are released. |
|
5. If not, back off, release the claim and wait for a few more milliseconds. |
|
6. Go back to 1 (until retry time has expired). |
|
|
|
|
|
Required properties: |
|
- compatible: i2c-arb-gpio-challenge |
|
- our-claim-gpio: The GPIO that we use to claim the bus. |
|
- their-claim-gpios: The GPIOs that the other sides use to claim the bus. |
|
Note that some implementations may only support a single other master. |
|
- I2C arbitration bus node. See i2c-arb.txt in this directory. |
|
|
|
Optional properties: |
|
- slew-delay-us: microseconds to wait for a GPIO to go high. Default is 10 us. |
|
- wait-retry-us: we'll attempt another claim after this many microseconds. |
|
Default is 3000 us. |
|
- wait-free-us: we'll give up after this many microseconds. Default is 50000 us. |
|
|
|
|
|
Example: |
|
i2c@12ca0000 { |
|
compatible = "acme,some-i2c-device"; |
|
#address-cells = <1>; |
|
#size-cells = <0>; |
|
}; |
|
|
|
i2c-arbitrator { |
|
compatible = "i2c-arb-gpio-challenge"; |
|
|
|
i2c-parent = <&{/i2c@12CA0000}>; |
|
|
|
our-claim-gpio = <&gpf0 3 1>; |
|
their-claim-gpios = <&gpe0 4 1>; |
|
slew-delay-us = <10>; |
|
wait-retry-us = <3000>; |
|
wait-free-us = <50000>; |
|
|
|
i2c-arb { |
|
#address-cells = <1>; |
|
#size-cells = <0>; |
|
|
|
i2c@52 { |
|
// Normal I2C device |
|
}; |
|
}; |
|
};
|
|
|