# Efficient display of simple text/graphics on color LCD by ARM

When designing an ARM-based device that should display simple graphics on a color LCD, how should one best go about designing things to allow fast updates, preferably without being tied to a particular ARM or LCD vendor? My current project uses a black-and-white display which can be driven lightning-fast by a the SPI port on a PIC (redrawing a complex display in 1/60 second). It seems common color LCD displays have an SPI port, but even filling a 160x120 LCD with a solid color would take 30ms, and a 320x240 would take 120ms best-case (10MHz shift clock).

If one could spare the controller pins, parallel mode could be better, but I don't know of any family-independent means of hooking up the parallel interface without requiring three separate memory-store instructions for each pixel (one to set the data, one to set the clock output high, and one to clock it low). Some ARM chips have memory-bus interfaces, but those often want to do things like multiplex address and data, or commit a lot of pins to outputting irrelevant address bits (the LCD would just need one address bit).

Looking at the ILI9320 by ILITEK, or the HD66789 by Renesas, one approach that would seem interesting would be to use a CPLD to convert SPI to parallel data, and include a mode which would output a pixel per bit. Looking at the Renesas data sheet, it might be possible to get pixel-per-bit writes with minimal hardware (no CPLD required) by making all the parallel-port data bits track the serial-data pin, using serial mode for everything but pixel writes, and using the compare/mask functions so that either all-zeroes pixels would be transparent and all-ones pixels would set selected bits in GRAM, or all-ones pixels would be transparent and all-zeroes pixels would clear selected bits. The "features" section of the IKITEK data sheet suggests that it has similar functionality, but the register maps don't seem to include the appropriate registers (most of the appropriate register addresses don't appear in the IKITEK, but one of them--register 4, is used for a different purpose).

Assuming the code will mainly be showing solid-color text and graphics, the ideal approach would seem to be to use a CPLD to interface the ARM's SPI port to the display's parallel port, and allow the CPLD to be loaded with foreground/background colors. This would be especially nice if one had a means of writing "transparent" pixels. Given a font as a two-color bitmap, one could simply load the font data directly into the SPI port; this would allow font data to be shown at a rate of one pixel every two ARM clocks. On the other hand, a CPLD sufficient to handle such a display-control task would cost about $2. What's the best way to interface an ARM with a color LCD, if the objective is to mainly to show solid-color text or simple (e.g. 16-color or 64-color) graphics? Edit I've done many LCD display projects, with many types of LCDs, including character-mode LCDs, custom 3:1 multiplexed segment-based using my own drive method, black and white graphic LCDs with built-in controllers, and black-and-white LCDs for which I designed my own CPLD-based controller to interface with a microcontroller's general-purpose DMA (providing four-level grayscale even). I pride myself on making displays zippy. One of the graphic controllers was a bit of a dog that required about 1/10 second for a full screen refresh even when writing constant data, but most of my displays can render even a fairly complex image in under 1/50 second. Many of the projects I do are battery-powered, so current draw is an issue. The DMA-based display controller I did worked nicely, but it was for a line-powered project. I believe the only way to get reasonable current draw from a graphics LCD is to use a controller which combines the display buffer and the column drivers. Sending lots of display between chips every frame would waste a lot of energy even on a single bit-per-pixel display; on a color display with sixteen bits per pixel, it would be far worse. I've only started looking at color LCD data sheets; many displays seem to use a controller similar to the ILITEK ILI9320, though all of the data sheets I've found for controllers based on that general design have been marked "preliminary". Some like the ILITEK one claim to have masking and transparency features but don't list any registers for them; I don't know whether the real chips have such features but the "preliminary" data sheets neglected to include them, or whether they omitted the features but forgot to strike the mention of them. If in practice all such chips have transparency features, it would seem reasonable to design for them; if not, not. I would expect that for most projects a typical screen would consist of arbitrarily-placed text in moderate number of arbitrarily-sized solid-color fonts. Fonts would most likely be stored as bit-per-pixel data. Using a Cortex-M3, if I wanted to write the display with parallel data, the code's "inner loop" to write two pixels would probably end up something like:  rol r0,r0,#2 ; Get one bit in C, the other in N itcs strhcs r1,[r3,#DATA_OFS] ; Write data strhcc r2,[r3,#DATA_OFS] ; Write data strb r4,[r3,#CLOCK_SET_OFS] ; Set clock high strb r4,[r3,#CLOCK_CLR_OFS] ; Set clock low itmi strhmi r1,[r3,#DATA_OFS] ; Write data strhpl r2,[r3,#DATA_OFS] ; Write data strb r4,[r3,#CLOCK_SET_OFS] ; Set clock high strb r4,[r3,#CLOCK_CLR_OFS] ; Set clock low  Not exactly the fastest thing in the world. Eliminating the writes to the set/clear clock instructions would help. My guess would be that there's no nice architecture-independent way to eliminate both clock writes, but there may be a pretty common way that would allow for eliminating one (e.g. many chips may have a counter/PWM that could be made to pulse an output briefly in response to a single memory store operation). Using the SPI port and adding hardware to clock one pixel per bit would greatly speed up display access. If using a display without masking and transparency, the CPLD would have to include an address counter, and for each pixel either clock a word of pixel data or else a set-address command for the following pixel's position (for which it would need a counter). By contrast, if a display had masking and transparency, all I would need to do would be to have the CPLD support a mode where after it had clocked in 16 bits, each additional bit would clock a word of data out to the display with the LSB tracking the SDI pin (it might not even be necessary to use a CPLD--just a few normal logic chips). I would set the transparency color to the be color I want to write but with the LSB flipped. I don't want to come up with a beautiful design that relies upon masking and transparency and then discover that the only displays with such features have a 30-week lead time. On the other hand, if such displays are apt to be and remain widely available from many vendors, I don't want to let paranoia about availability drive me to use an inferior design. • Not an answer since your requirements include not being tied to a specific ARM vendor, but the LPC LH754xx family of microcontrollers includes an integrated LCD driver. – Kevin Vermeer May 5 '11 at 19:26 • @reemrevnivek: There are a number of ARM chips with small LCD drivers; I can't imagine any chip having a driver suitable for any useful size graphics display appearing in a package that would be usable in anything other than a chip-on-glass scenario. A chip might have a controller, but an LCD with a chip-on-glass controller would seem more power-efficient and easier to work with. I'll check out the chip you mentioned, though--might be interesting. – supercat May 5 '11 at 19:49 • @supercat - I'm thinking of LCDs that have an RGB interface: pixel clock, frame sync, and line sync control lines, with a parallel pixel data bus. Are you expecting to use a COG controlled display? – Kevin Vermeer May 5 '11 at 20:11 • @reemrevnivek: That's what I'd been thinking. They seem to be pretty common, since they're used in a lot of portable battery-powered devices like cell phones. A COG display with built-in controller is going to be much more power-efficient than one which requires continuously-clocked RGB data. – supercat May 5 '11 at 21:01 • @reemrevnivek: I just updated my question with more detail. – supercat May 6 '11 at 15:53 ## 1 Answer The problem with using a microcontroller to drive an LCD is that an LCD requires constant attention. This can be mitigated with a CPLD driven over SPI (using DMA, of course), but then you run into the other problem: Color LCDs require a lot of data. 320x240 in black and white is marginal at 9.6KB, but make it 24 bit color and suddenly you need to deliver 230KB of data in 1/60th of a second. (Don't forget, though, that you can get 4-bit, 16-color control just by tieing the low 20 bits to one setting). A 24-bit frame buffer no longer fits in onboard RAM on most microcontrollers, and you probably don't have time to read from an external RAM chip, clock the data out, and still do other processing. Trying to do this with a CPLD (or an FPGA) and a RAM chip gets you well over the$2 price that caused you to balk in your question.

The traditional solution to interfacing a microcontroller with a color LCD is a display controller like an SSD1963. Here's a very simple block diagram:

Parallel input to a big RAM frame buffer (Translation: More than \$2) interfaced with a register-configurable parallel LCD interface. The parallel input is usually compatible with a memory bus interface.

The color LCD market is not always easy to find on the web, usually being the domain of OEMs only, with the rest buying displays from companies who integrate the controller with the display. The best resource I've found has been Crystal Fontz, specifically this page on choosing graphic LCDs. Scroll to the bottom for the controllers, which include the following options (note: Not all are color controllers):

• Epson S1D13521B01 E Ink Broadsheet (1 module)
• Epson S1D13700 (11 modules)
• Epson SED1520 Compatible (8 modules)
• Himax HX8345 Compatible (1 module)
• ILITek ILI9325 Compatible (3 modules)
• KS0107/KS0108 Compatible (26 modules)
• Novatek NT7534 (14 modules)
• Orise Technology OTM2201A (1 module)
• Orise Technology SPFD5420A (1 module)
• RAiO RA8835 (1 module)
• Sanyo LC7981 (13 modules)
• Sino Wealth SH1101A (2 modules)
• Sitronix ST7920 (29 modules)
• Solomon SSD1303 (1 module)
• Solomon SSD1305 (9 modules)
• Solomon SSD1325 (2 modules)
• Solomon SSD1332 (1 module)
• Solomon SSD2119 (2 modules)
• ST STV8105 (1 module)
• Toshiba T6963 (23 modules)
• @reemrevnivek: I'd been thinking of color LCDs with built-in controllers. They seem pretty common, but the ones I've seen generally seem to expect the CPU to clock in many bits per pixel even though a common display scenario is the display of solid-color text. I implemented a DMA-based 4-level grayscale LCD controller once using a CPLD, and it worked very nicely, but that was a line-powered device. – supercat May 5 '11 at 21:04
• @supercat - Very few LCD controllers expect a CPU to clock many bits per pixel in for each frame. They generally are expecting dedicated graphics hardware to be doing this. Basically, once you get to fairly large (i.e. > 128*128) RGB displays, the processing power required to generate the image for the screen is large enough that a dedicated GPU of some sort (even if it is integrated into the MCU) is pretty much always present. – Connor Wolf May 7 '11 at 5:35
• @Fake Name: If the goal was to display full motion video, some specialized hardware would be necessary. But my goal is to display plain text and simple graphics, quickly. The controllers I've been looking at have a maximum SPI data rate of 10mbps; that limit would apply whether the data was being supplied by a CPU or a dedicated controller. Using a parallel-input mode would speed things up, but if character shapes are stored with 1 bit per pixel (as would be typical) using code to unpack them would be slower than having the ARM output SPI and having a CPLD convert that to parallel data. – supercat May 7 '11 at 7:17
• @supercat - But what you describe, a specialized CPLD that does ASCII to raster conversions, basically is (custom) specialized graphics hardware. I'm basically saying don't re-invent the wheel, and it's probably easier and more cost-efficient to just buy a MCU with a video-interface built-in then design one yourself. – Connor Wolf May 7 '11 at 7:27
• Anyways, If you really want to roll-your-own, I would say use a couple of dual-port SRAM ICs, and use one port for outputting to the LCD, and the other for the MCU. This lets the MCU change the memory contents at whatever speed it wants, and the LCD can run at it's refresh rate. – Connor Wolf May 7 '11 at 7:29