Monday, June 13, 2011

The frustrations of what whould be simple...

Why I always seem to have the most problems with the things that should be easiest and the fewest problems with those that should be hard I will never know.  Lots of frustration working out the I2C interface between the backplane controller and the card controllers.

For the alpha backplane I am using an 18F26K22 microcontroller from Microchip - it's primary role here is to control the activation state of the cards (power on/off - run/idle - clear/reset) over the I2C bus.  On the cards I am using MSP430s (G series depending on requirements).  The significantly more powerful PIC on the backplane will also connect to a low voltage serial bus for console control/debugging and has wiring for an SPI bus across the cards with individual enables and a global master enable.

Doesn't sound difficult right... (I didn't think so either) -> but then you have to add the fact that I hate having to externally program cards after the debugging stage (which for the I2C bus I would need to - especially for multiple cards of the same type)... so I decided to have all the cards start with the same I2C address (as a default) and then identify them and assign a unique address for the I2C bus with the backplane controller.  I decided to do this by having the cards behave differently when the master enable (MSTEN) is low or high.

When MSTEN is low AND the unique enable is high the controller on the card will assign the byte written to it over the I2C bus to a new unique address on the I2C bus.  Once a card has a unique (non default) address it will always listen to the I2C bus and bytes written to is will set the board state (power/reset/run conbinations) and it will respond to the master with data about the card's identity, intentions, activation state and potentially additional data.

Even this shouldn't be that difficult, but then I ran into some problems... The TI controllers allow me to use interrupts (lots of them) to handle various changes in the pin states - it took a bit more work than I expected to really understand the many control bits and the way the flags are triggered and reset - would have been easier to do in software but I wanted an interrupt implementation (for the the I2C on the USI controller and the Port2 IO control (MSTEN and EN1) signals because of some potential things the controller will have to do on future cards...  The PICs don't have lots of interrupts, but they have a well thought out set of registers and flags that work nicely (but from a very different overall design perspective).

Lots of subtle little things about the ways each was designed and implemented (one of those learning curve things - turned out steeper than I expected).  It was made worse by the fact that I only had random 5 to 15 minute intervals to work on it lately (which is fine for software but not for this - at least for me).  Finally I set aside a few hours and worked through everything and not the basics (idle scan mode/set addresses, read states) works.  I still need to write the card specific code for the apricot card (FPGA) and then signal testing can start (this should be a lot easier since the framework works now).

One a different note, the worst signal interference I found (granted that these are not very high edge rate changing voltages) wasn't as bad as I expected - (here's a 100 fold difference in the scales here (but the same heights for full voltages).  Here the card specific enables are walked (yellow for slot 4) and one of the neighboring differential pairs is monitored (blue) - no termination.

Still lots of work to do, but when I finally get past something that was more frustrating than I expected I kind of need to vent a bit... The sources are here and here (although not fully complete - the I2C stuff is functional for interrupt I2C implementations.