Question : Right way to implement GPIO interface

So we need to make two microprocessors talk to each other.  One is a master, and one is a slave, and we want to send back the current state from the slave to the master (e.g., init, ready, busy, error, etc).  We figure the simplest way to do this is with just plain I/O (GPIO) lines, slave micro sets one or more lines, master micro polls them.  

So the very, very easy way to do it is each pin indicates a state

Pin 0 active: Init
Pin 1 active: Ready
Pin 2 active Busy
Pin 3 active Error

However we could conserve GPIO by doing it with two pins

Pin 0 inactive, Pin 1 inactive: Init
Pin 0 inactive, Pin 1 active: Ready
Pin 0 active, Pin 1 inactive: Busy
Pin 0 active, Pin 1 active: Error

Note this uses two pins instead of 4.  However, I think in the second technique we run the risk of catching a transition.  For example, the slave tries to transition from INIT to ERROR states so it changes the first pin from 0 to 1, then changes the second pin from 0 to 1.  However, if the master polls in between the two changes it would read 01 or 10, which is READY or BUSY, and it might take a bad action.

So the answer is probably to use a third pin, which indicates the validity of the other two.  The slave sets that pin low, then makes the changes, then sets it to high again, meaning the other two bits are valid.

So this would take three pins, which is still a savings over the 4 required by the first approach.

Can I get a sanity check on all this?  The second approach is preferable, right, provided we use the extra pin technique?  That is necessary right?

Thanks for any thoughts.

Answer : Right way to implement GPIO interface

You're pretty much got it exactly right, but to put it slightly differently for you:

1) Your first proposed method lets you keep track of four discrete "variables", each one able to take on one of two different values (high or low). This uses four pins, and there are 16 possible states of your bus line.

2) Your second proposed method lets you keep track of one single "variable" which can take on one of four different values (00, 01, 10, or 11). There are 4 possible states to your bus line.

From what you described, method #2 suits your purposes better. If you do it the #1 way, you will have a bus line which has 16 possible values, but only 4 of the possible 16 values have any meaning to you (0001, 0010, 0100 and 1000). Everything else is invalid. So that's a waste of resources. That's why you save a couple bits by doing it the method #2 way.

Now the important thing to note is that no matter which method you use, #1 OR #2, you will always have the "unstable state" issue. There is always that infinitesimal amount of time when the master is changing the value on the bus line, and if the slave reads at that exact moment it will get an incorrect reading.

You proposed a "synchronizing clock bit" which both master and slave share. You called this the validity bit. The clock bit is set by the master, and read by the slave. The master ensures that upon the rising edge of the clock the value on the data bits is stable. The slave knows to read the data bits only when the clock goes high. This can be done directly in hardware at the signal level (e.g. a verilog or VHDL circuit programmed onto an FPGA), or you can do it at a higher level (e.g. a microprocessor like an Altera board which has a hardware interrupt thrown when that sync bit goes high).

So basically I think you're completely correct, just realize you still saved 2 gpio pins, not just 1, because even if you did it the first way you'd still need the synchronization clock bit.
Random Solutions  
 
programming4us programming4us