yeah, this is definitely not working well in practice, but the problem doesn’t manifest itself in quite the way I expected.
Crow can trigger scripts rapidly while TI.PRMs work in Live mode, but as soon as a script is triggered that contains a TI.PRM OP, that OP returns 0 and Teletype apparently ceases to even try to lead (all future TI.PRMs return 0 until I power cycle). But it’s still able to follow messages from Crow, and Crow is able to send & receive to/from TXi – that’s the surprising part, I expected maybe the whole bus might freeze, or one of the modules would stop responding completely, but that’s not what happens.
I poked around a bit and found an article about problems using multiple “master” AVR units – the problem as described there doesn’t really match what I’m seeing, but I wonder if the cause might be related. Will continue to experiment.
Update: I got a version of this working last night (10/24), and it’s been working well today too. Heck yeah.
The important changes to my branches of teletype and libavr32 are:
- Added a new I2C/TWI interrupt handler, different from the ones in the Atmel ASF code. It’s basically both the “master” and “slave” handlers rolled into one, but it’s also designed to pay closer attention to the
TXCOMP bit in the TWI status register. That takes care of the issue I described above: TT was refusing to follow because once an attempted read/write failed due to the bus being busy, twi_busy would remain set to true, which would block all future attempts to read/write to the bus, even though TT could continue to respond to incoming messages from Crow. Adding a whole new interrupt handler is probably overkill for this; if it’s okay to make edits to the ASF code (and I see it’s been done before, in order to make it possible for I2C reads/writes to time out), then that problem can probably be fixed with a lot less code.
- In addition to checking
TXCOMP before switching between leader & follower roles, the new code tries to check whether either the SDA or SCL lines are low, and watches for the ARBLST status register bit going high. Both are further indications that the bus is busy, but so far I haven’t seen either of those conditions actually happen while TXCOMP was high, so monitoring TXCOMP alone may be sufficient.
- Instead of running scripts immediately when I2C messages are received, TT now adds II events to the main event queue, and scripts triggered over I2C are run from the event loop.
Using this code I’ve been able to trigger four TT scripts (containing TXi reads) from Crow roughly every 100ms, while running a metro script at 20ms that also reads from TXi, so it seems to be doing the job!
Happy to provide binaries to anyone who’s interested in testing, and I also welcome critique of the code or ideas about where it should go (should it sit alongside the existing i2c code in libavr32 like it does now, or replace some of it, or just live in the TT codebase, or…?) if it were to be merged in.