3 wire DLG2416 CPLD Display Controller
After finding the DLG2416 quite useful it's also a very I/O hungry display to use. It's pretty obvious when looking at the spec sheet (7 data lines, 4 address lines, write latch, clear etc.) that the display was designed to live on a nice fat bus with heaps of I/O room, but in micro-controller land we have to be fugal with our use of I/O.
Looking for a solution I though of using a pair of 74HC595s and doing all the control in software like I've done with my 7 seg display and my HD44780 SPI display. But I wanted something similar to the way the HD44780 talks. I wanted something that I can push a string of characters to and it looks after the position etc. I wanted to offload the "software" communication requirements to some logic so that using the display was as simple as clocking data into a register and setting a latch. This lead me to use a CPLD.
The CPLD I chose was an old XC9536 from Xilinx. I found a tray of 20 of them for like $15 AUD on ebay. Not being sure if they were internally big enough I figured I could use them for something else if they weren't suitable. Turns out after some initial fiddling they where more than adequate for the task.
Writing the controller in Verilog was fun. I like trying new things and it is very different to my usual way of thinking, but once I understood the concepts I felt right at home and very productive.
In my design I ended up with a simple 9 bit shift register that the controlling micro-controller shifts data into. This data is made up of two "command" bits and seven "data" bits. The micro-controller sets a latch that triggers a state machine to look at the command and decide what to do with the given data.
The support command set is very simple. You have a "clear", a "load character into current position", a "load character into current position and advance position", and a "goto position".
| C1 | C0 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Description |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | X | X | X | X | X | X | X | Clear/Reset display |
| 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | Load 'A' into current pos. |
| 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | Load 'A' into current pos. and advance pos. |
| 1 | 1 | X | X | X | X | X | 0 | 1 | Goto pos. 1 |
So by using these simple command you can pretty much just send straight ASCII at the controller with an additional two bit and you're done! No tricky software required.
As it stands the CPLD has enough addressing outputs to handle four displays (16 characters) without external decoding. But given for every four I/O pins used (two with external inverters) and the additional two internal addressing bits you can easily add four more displays. With the space left in the CPLD I could see making a 48 character display no problem.
The timing report of the CPLD says the design is good for up to 100MHz, I'm currently running it at 8MHz using a simple pierce gate oscillator. The speed of the clock determines how fast the state machine can accept new commands from the shift register. The "Goto" and "Clear" commands take one clock cycle, while the two "load" commands take two. The DLG2416's are also good for around 10MHz update rate so I think my 8MHz clock is a great fit.
I've been testing the design with my Bus Pirate in 2wire mode and using the AUX pin as the latch. It works quite well but unfortunately doesn't support binary output of anything larger than 8 bits so I'm having to manually transition the pins using '-' for high and '_' for low and '/\' to pulse the AUX latch. Fun! But it does work. The Bus Pirate can also only clock data at 400KHz which means the display update is a little slow when doing multiple characters. Coming from a micro-controller with anything above 1MHz clock speed should be unnoticeable in update.
I'll upload the verilog and a programming file once I'm completely happy with it. All in all it's been a really fun project. Now I just need to make a PCB and send the design off to make a bunch of handy 16 character LED displays! :)