Fast Updates on Sharp Memory LCDs

Background

Monochrome liquid crystal displays have been in existence for many years. The original use case was for super low power segmented displays on calculators and watches. Each display segment was directly controlled by the microcontroller and required a tiny bit of power to hold it in the 'on' state. Over time, APA (all points addressable) aka dot matrix displays were created to show images and more complex data. The traditional method of creating a dot matrix LCD display is to have a dedicated controller (simple MCU), RAM and a communications interface. This is how almost all modern dot matrix LCDs are made (see Sitronix LCD controllers). This allows for very high resolution displays to be managed with a simpler command interface and the dedicated controller chip is responsible for scanning the rows and columns to keep the LCD pixels current with the RAM contents. Dedicated dot matrix LCD controllers simplify utilizing these displays in products, but they come at a cost - power. A typical monochrome LCD controller uses between 100 and 700uA at 3.3 Volts compared to LCD segments which are normally in the single digits of micro Amperes. Sharp invented a lower power way of managing large dot matrix LCDs. They created a line of LCDs called "Memory in Pixel" or just "Memory LCDs". The idea was that each dot of the display was directly tied to a static RAM bit and there was no need for a controller to be constantly scanning rows and columns. For the external MCU to access the display RAM, a simple state machine was created which allows the RAM of each row to be changed. This state machine was exposed as a SPI interface.

The Command Set

Memory LCDs support the following 4 byte commands:

Write line - write an entire line of pixels
Write multiple lines
Clear screen - write 0 to all pixels
Toggle VCOM (the charge balance signal; it can come from here or an external pin)

The Write Line command is structured as follows:

<cmd> <line number> < data bits > <0x00> <0x00>

The entire line must be written in one transaction or it won't get updated (e.g. on a 400 x 240 display, it would need 50 bytes of pixel data written for each line).

The Write Multiple Lines command is structured as follows:

<cmd> <line number> <data bits> <0x00>
<line number> <data bits> <0x00>
<final line> <data bits> <0x00> <0x00>

You can write non-sequential lines if you like. The SPI data is sent as one continuous block.

This multi-line option looked like a good way to accelerate display updates. My initial thought when seeing this command was to use a temporary buffer to assemble the necessary data (command byte, line numbers, pixels and terminating bytes), then send it as a single block. I did this as my first try and it worked as expected. By eliminating the toggling of the CS (chip select) for each line being sent, the multi-line mode allows multiple lines of data to get to the display faster.

The Next Logical Step

Well...after thinking about this a bit more, I came up with the idea of making my framebuffer conform to the way Sharp needs the data sent in a multi-line command. Translation - I created a framebuffer for my software which has the multi-line command, line numbers and stop bytes built-in. I arranged it such that the 'pitch' of each line of graphics is the pixel data size + 2 (line number + stop byte). I then changed my character/sprite code to use this new pitch and starting offset for all drawing operations. My display initialization code now sets up the start/end bytes for each line (once). The rest of the display code just draws "in between" these bytes. When I need to update the display, I can send the entire framebuffer in a single transaction without any temporary buffer needed. On my latest MCU projects, this allows me to use a single DMA transaction to update the entire display. For example, on my projects which use the 160x68 Sharp LCD, I can push data to it at 8Mhz and update the entire display in about 1.5 milliseconds (start byte, 20*68 pixel bytes + 68*2 line#/stop bytes, final stop byte = 1498 bytes total). This saves time, but more importantly it saves power.


Pictured above is my latest Pocket CO2 detector project with a 1.1" 160x68 Sharp Memory LCD.

If you would like to see some code which implements this idea, you can see my C code for the CH32V003 portable sensor platform here:

https://github.com/bitbank2/CH32V003_Sensor_Platform/blob/master/User/sharp_lcd.c

 

Comments

  1. Great post and code. No wonder WCH shop on AliExpress is selling these LCD's at $12.50 (£10) each to pair with the cheapest RISK-V chip on the market CH32V003 @ around $0.20. I try to keep up with you, but experience counts! Perhaps you could bond a CH32V003 to the back of the LCD itself and sell Sharp the concept of your low power SSD 1306 OLED replacement project. Sharp state that they do not sell to other than watch/instrument manufacturers, presumably because of the support problems of the updating software and the need for external clock source. You have definitely cracked these issues in a comprehensive way and I hope they take notice and loosen the resale policy to at least allow, say AliExpress resellers to be more competitive and realistic about pricing about the pricing

    ReplyDelete

Post a Comment

Popular posts from this blog

How much current do OLED displays use?

Fast SSD1306 OLED drawing with I2C bit banging

Building the Pocket CO2 Project