Dakota Digital PV2 (Red) Single-Use Digital Camera - hacking the LCD for your own projects

The Base Idea: (basically a shameless copy of my own post on the linux-hacker.net BBS)

[U]sing the LCD for a hobby project looks like it will be a minor mess, due mostly to the LCD's timing requirements. For example, you can run most PICs with an external oscillator of up to 40MHz (just watch for "but it screws up above 4MHz" in the errata sheets), which because of the 4-clock instruction cycle gives an instruction clock of 10MHz. So this means that even if your PIC code did nothing else except flip a clock line up and down, the maximum rate you could clock at (set line high, then set line low) is 5MHz, still not fast enough to drive the LCD.

But now you've got me thinking....

What probably needs to be done, is to implement a basic "clock data into the LCD from a memory at 5.67MHz" circuit on an FPGA. I guess you could even do this with a bunch of 74LS... chips but this could get messy. Then use your PIC to control the image that's actually in the memory. You of course won't be able to display anything at a video-like frame rate, but this should be fine for static images.

"But how do I update a memory while the FPGA is reading from it?"

There you're on your own. What I would do personally is implement a 'disable' pin on the FPGA, which would float the pins tied to the memory. Then you can rewrite the video display at your leisure with the PIC (nothing is being displayed on the screen at this time), then re-enable the memory access to the FPGA. If you want to get fancy and avoid blacking out the screen while changing the image, there is such a thing as 'dual-port' (or multi-port) memory, which can be read and written at the same time via separate address/data lines. Haven't checked how expensive this stuff is, though. You could also time it so that your PIC races in and changes the video memory during the "blank interval" (the little bit of downtime between writing the last pixel of the current frame, and the first pixel of the next frame), but that doesn't give you very much time at all.

You'll need up to 64KBytes of memory for the 280x220 image, depending on how you store it in memory. Remember that the "pixels" on the LCD are actually individual, staggered RED / GREEN / BLUE dots, not the standard square matrix of any-color pixels you're probably accustomed to. So, your PIC (or PC program talking to it, etc.) will have to do some translation to convert bitmap images, text, etc. to a format that will display correctly on the LCD. The 280x220 refers to these *dots* as far as I can tell from the datasheet; so the 64KByte figure is accurate if you store the data in the logical "1 byte -> 1 dot" way. The LCD only uses 6 bits per dot though; so you have an extra 2 bits per dot where you can store whatever you want (or nothing at all).

What I would probably do (considering I had a nice big FPGA to play with) is use the 6 bits to store an actual "true-color" background image, and use the remaining 2 bits to specify one of four programmable "overlay modes" for that pixel. The FPGA would have to do the overlaying in real-time, but this would allow you to set e.g. an overlay color and mode for each of the 4 possible slack-bit settings.

E.g.: Mode 0: Transparent (do nothing); Mode 1: Set this pixel to user-defined color [Bright Red] (ignore 6-bit color information); Mode 2: Add user-defined brightness (0x26) to 6-bit value before writing it to the LCD...

This way you could display e.g. text (quote of the day, weather reports, time/temperature) over a background image, without altering the original image and without requiring another 64KBytes of expensive memory as a frame buffer to store the original (for when you want to erase/change the text). Changing the entire text from, say, opaque fuschia to smoked-glass transparent would be as simple as writing 1 or 2 bytes to the FPGA (or a couple of the slack bytes at the end of the RAM, which the FPGA will read during the blank interval).

Limitations of the above

It's just my late-night brainstorming (and there may have been a little Scotch involved, so beware of drunk sincerity or general nonsense). There are dozens of alternate approaches, such as just using a faster proc (or taken to the extreme, "rape an old Pentium out of a throwaway motherboard from your basement and..." in other words, interface it directly to a PC), or stick with discrete logic chips all the way (mainly binary counters and the related trip logic to clock data from an external SRAM and generate the necessary V/H sync pulses and blank interval), keep the FPGA but skip all the icky complexity of implementing overlay registers, etc., etc...

The big limitation is that with 2 overlay bits you get 4 overlays...you can define and re-define each of them as any 'color' you want, and any operation (replace/add/subtract/AND/OR/XOR/etc...subject to how complex you want to make your FPGA) per overlay, but these are still acting per 'dot' (red/green/blue)...so if you generated some pattern/text and wanted it to show in a very specific color, you could theoretically use up all your overlays there alone - one each for the {red, green, blue} pixels and the fourth defined as transparent (for all the pixels you're NOT overlaying stuff on). You could still get away with generating overlay patterns using up only 1 overlay, but this limits you to using that overlay e.g. for only the RED pixels, or else setting two or more of the pixel colors {red, green, blue} of that pattern to the same overlay number (making them the same intensity - for example, set them all, and your overlay is a 'shade of gray' no matter what the overlay 'color' value or background color).

With the extra logic operations mentioned (or some custom operations), combined with a user-definable overlay color, these could be extended somewhat; e.g. you could encode extra information into the least significant bits of each pixel's intensity, which a normal human eye is not likely to notice.

If you want to get really fancy, you could plop down a 128KByte SRAM instead, or a 16-bit-wide one and use the other 64KByte as a frame buffer or for overlay purposes. If you want to get fancy. Or a second simple (FPGA) memory controller and SRAM, this one shovelling data from RAM#1 to RAM#2 during the blank interval, so instead of the blank interval itself, your micro has (all the time in the world minus blank interval) to update the display, without actually disabling the screen image to write to it.

Hardware

LCD datasheet (and partnumber): A015AN02V1.pdf

Mini 32-pin flex connector it plugs into: Omron makes a compatible connector, the XF2H-3215-1LW. This is available from Mouser for under $2, and theoretically from Digikey as well (though not in stock when I checked). If no joy, try without the -LW; this is just the same part with better plastic. Unfortunately the connections to the flex connector are just as tiny as those on the LCD itself; you'll probably want to lay out an actual PC board to solder it onto (rather than try to solder tiny wires directly to it)...the purpose of using the connector is to keep from messing up the flex ribbon on the LCD itself. In any case, get your magnifying glass handy.

LCD drive circuitry (voltage generation, etc.): A sample circuit is provided on the last page of the datasheet; it appears to provide all the necessary secondary voltages and signals required by the LCD. Although they specify some specific (and rather obscure for hobbyists) transistors and such, they can probably be substituted with generic Digikey fare without any trouble.

Back to Dakota PV2 info