It's been a few days since I last posted something. I've been busy. Anyway...
The Spacehack game used lots of Nokia 5110 LCDs. Each console had one Beaglebone Black in it which had to control up to three of these Nokia LCDs. When we took Spacehack to Makerfaire UK 2014, the Nokia LCDs were connected to GPIO pins which were controlled by a software SPI library. The problem with bitbanging (wikipedia link) in this case is that it is slow. Especially when you have a high level language like python sending commands down a relatively large stack of software before reaching the hardware. This is a problem that we tried to solve before the Makerfaire but didn't.
The Beaglebone Black does have some hardware SPI. If I recall correctly; it has two SPI devices, one of which is usually in use for something internal, can't remember what. So anyway, this looked like it was going to limit us to just one Nokia LCD at the most. This is not good.
Nick and John from the hackspace (York Hackspace) put some effort into trying to solve this problem. The first thing to try was to connect all the Nokia LCDs to the same SPI pins and then use GPIO pins to do the CE pins for each LCD individually. This sounded like a fairly obvious and simple solution to the problem. The only thing is that the LCDs expect the CE line to be pulsed regularly as the controller writes to them. The CE line almost becomes a clock signal. This made the solution not as simple as asserting the LCD's CE line. It wasn't possible to emulate this behaviour unless reverting back to the bitbanging method which we were trying to get away from.
The solution was both simple and ingenious. I think it was John that suggested it, although it might have been Nick. The solution was to have a logic gate driving each chip enable line. By connecting one input of an OR gate to the real CE line on the BBB and then connecting the other input to a GPIO pin, the output of the gate will be either the output from the real CE line or simply a logic '1'. Setting the GPIO output high is then effectively blocking the CE from the LCD that it controls. When the same GPIO pin is low, the signals from the real CE line get through to the LCD. Perfect!
A not for those that may be wondering; we couldn't use an AND gate as the CE line is active low. The behaviour of the LCD might then be undefined when it is not selected. A NAND gate wouldn't solve the problem either as this would invert the real CE signal. You could place an inverter on the real CE line but then you have extra logic to implement, considering that you can also invert the control input in software if you wish then you effectively have, by De Morgan's theorem, the equivalent of an OR gate. Thus making an OR gate the optimal solution.
At this point, John tried making this happen with some DRL (Diode-Resistor Logic). The circuit was simply an OR gate for each LCD made from one diode and one resistor. The anode of each diode is one input to the logic gate, this was connected to the real CE line. The cathode of each diode was connected to a resistor and also to the CE line on an LCD. The other side of that resistor was effectively the other input to the OR gate and so this was connected to a GPIO pin on the BBB to allow control by the BBB.
The theory is demonstrated below...
This explanation will be obvious to some, you may skip it...
Diagram 1 shows the connections.
Diagram 2 shows that when both inputs are low, there is no current through the diode as the anode is tied low and the cathod is pulled low through the resistor, therefore the output is also pulled low.
Diagram 3 shows that when the diode anode is high, there is a potential difference across it, current flows through the resistor and then through the diode. (Electron flow, not conventional flow. If you like to think of the diode arrow as the direction of flow then shame on you.) enough current is flowing for the diode to have a negligible resistance and so the output is effectively connected directly to the 'High' on the diode input.
Diagram 4 shows that when the resistor input is high, the diode input has no effect on the output. In this case, the cathode is at a positive voltage and so the anode can't get any more positive than the cathode, therefore there is no current flow in the diode, the output is effectively connected to the resistor input.
Diagram 5 can be explained by diagrams 2 and 3.
(End of explanation)
So there we go. This worked perfectly and hardware SPI was good to go.
The full solution is this:
We used 1N4148 signal diodes and 10k resistors. The remaining LCD connections are all bussed together and connected to the standard SPI pins on the BBB.
See John's gist for some code to run the things.
From this circuit, I designed some PCBs that did this logic and adapted the LCD connectors to something more convenient.
Here it is in action: