Display driver for Sharp's range of SPI-driven memory LCD's, leveraging the power of asynchronous transfers. Currently supports LS013B7DH03, but easily extendable to other models as well.

Dependents:   memLCD-Demo memLCD-Demo memLCD-Demo MemLCD-Temperature-Humidity-Demo ... more

Information

All examples in this repo are considered EXPERIMENTAL QUALITY, meaning this code has been created as one-off proof-of-concept and is suitable as a demonstration for experimental purposes only. This code will not be regularly maintained by Silicon Labs and there is no guarantee that these projects will work across all environments, SDK versions and hardware.

Memory LCD extension board

Caution

This library builds upon the asynchronous SPI interface provided by mbed, but not all platforms currently support this. So, make sure your platform is capable of asynchronous SPI (all Silicon Labs platforms are), otherwise you will get compiler errors!

Usage

The library is purposefully quite simple to use. To set it up, you initialize an SPI object and the required I/O pins, and call the library constructor with those. Make sure the display is powered on, enabled, and the inversion mode is set to external (EXTMODE is high).

setup

#define SCK     PD2
#define MOSI 	PD0

DigitalOut CS(PD3);
DigitalOut EXTCOM(PC4);

SPI displaySPI(MOSI, NC, SCK);
silabs::LS013B7DH03 display(&displaySPI, &CS, &EXTCOM);

You should also swap out the pin names for the relevant names on your platform.

After setup, you usually want to clear any static information left on the screen. To do that, you would call clearImmediate, and optionally provide a callback. The callback will get called when the clearing operation is complete and the display has been cleared. In this example, refreshCallback sets a global boolean 'refreshed' to true when called.

clearing the display

refreshed = false;
int result = display.clearImmediate(refreshCallback);
if(result == LS013B7DH03_OK) {
    while(refreshed == false) sleep();
} else {
    printf("Display error: %d", result);
}

Of course, instead of sleeping while the display is clearing, you could also just continue with the program, and check back whether the callback happened or not.

Then comes the fun part, actually writing stuff on the display! Since the display only supports one-way communication (i.e. you cannot read from it), it uses an internal frame buffer in RAM. So, to actually display something on the LCD, two steps need to happen: writing to the pixel buffer, and at the very end writing the pixel buffer to the LCD.

Pixelbuffer operations

The MemoryLCD library builds upon Simon Ford's TextDisplay library, which means you can use all of that functionality. Even printf is supported!

most important display operations

// Set one pixel at x=10, y=40 to the color White
display.pixel(10,40,White); 

// print "I love mbed" at the character position x=4, y=5
// i.e. starting on row 5, 4 characters from the left border
display.locate(4,5);
display.printf("I love mbed!");

// show a bitmap at a given location
// Constraints: bitmap is 8-bit, MSB first, 1 bit per pixel. Width, height and starting coordinates must be divisible by 8.
// This example: show a bitmap which is 128 pixels wide and high, and start at location 0,0.
display.showBMP(&mbed_logo, 128, 128, 0, 0);

//Draw a line (really a 1px wide rectangle) from (4,10) until (4,15)
display.fill(4, 10, 1, 5, White);

Updating the LCD

Updating the LCD (i.e. moving the framebuffer to the display) happens much the same way as clearing it: asynchronously. To start the update, you call update() on the display, optionally providing a callback to be called after the whole update has happened. In the example below, refreshCallback sets a global boolean 'refreshed' to true when called. Signature: void refreshCallback(void);

updating the display

refreshed = false;
int result = display.update(refreshCallback);
if(result == LS013B7DH03_OK) {
    while(refreshed == false) sleep();
} else {
    printf("Display error: %d", result);
}

Full example

example program

#include "LS013B7DH03.h"
#include "mbed_logo.h"
/******************** Define I/O *****************************/
DigitalOut myled(LED1);

#define SCK     PD2
#define MOSI 	PD0

DigitalOut CS(PD3);
DigitalOut EXTCOM(PC4);
DigitalOut EXTMODE(PD4);
DigitalOut DISP(PD5);

SPI displaySPI(MOSI, NC, SCK);
silabs::LS013B7DH03 display(&displaySPI, &CS, &EXTCOM);

/******************** Define Timers *****************************/

LowPowerTicker timeKeeping;

/***************** Define global variables **********************/
#define INIT_SECONDS		17600

volatile uint32_t prevSeconds = INIT_SECONDS, seconds = INIT_SECONDS;
volatile bool refreshed = false;

/***************** Define callback handlers *********************/
void secondsCallback(void);
void refreshCallback(void);

void secondsCallback(void) {
	seconds++;
}

/**
 * Callback for refresh completion
 */
void refreshCallback(void) {
	refreshed = true;
}

/*************************** MAIN *******************************/
int main() {
    // Enable the LCD
	EXTMODE = 1;
	DISP = 1;

	// Start generating the 1Hz call for keeping time
	timeKeeping.attach(&secondsCallback, 1.0f);

	// Reset the LCD to a blank state. (All white)
	refreshed = false;
	display.clearImmediate(refreshCallback);
	while(refreshed == false) sleep();

	printf("Initialization done! \n");

	// Apply mbed logo bitmap to the pixel buffer
	display.showBMP((uint8_t*)mbed_enabled_logo, 128, 128, 0, 0);
	display.printf("I like MBED!");

	// Push update to the display
	refreshed = false;
	display.update(refreshCallback);

	// Sleep while doing the transmit
	while(refreshed == false) sleep();

	// Go into clock mode
	while(1) {
		sleep();

		// In clock mode, only update once per second
		if(prevSeconds != seconds) {
			display.locate(4,15);
			display.printf("%02d:%02d:%02d", (seconds / 1200) % 24, (seconds / 60) % 60, seconds % 60);
			if(refreshed == true) {
				prevSeconds = seconds;
				refreshed = false;
				display.update(refreshCallback);
			}
		}
	}
}

Datasheet

Datasheet for the LCD (hosted by Mouser)

Committer:
stevew817
Date:
Wed Aug 12 14:06:07 2015 +0000
Revision:
11:0f8ae10b308d
Parent:
4:b02dfd360729
Implement Paul Staron's enhancements to the display driver classes, from https://developer.mbed.org/users/star297/code/MemoryLCD/rev/b64f87859c57

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Steven Cooreman 0:a0faa86660d4 1 /* mbed TextDisplay Library Base Class
Steven Cooreman 0:a0faa86660d4 2 * Copyright (c) 2007-2009 sford
Steven Cooreman 0:a0faa86660d4 3 * Released under the MIT License: http://mbed.org/license/mit
Steven Cooreman 0:a0faa86660d4 4 *
Steven Cooreman 0:a0faa86660d4 5 * A common base class for Text displays
Steven Cooreman 0:a0faa86660d4 6 * To port a new display, derive from this class and implement
Steven Cooreman 0:a0faa86660d4 7 * the constructor (setup the display), character (put a character
Steven Cooreman 0:a0faa86660d4 8 * at a location), rows and columns (number of rows/cols) functions.
Steven Cooreman 0:a0faa86660d4 9 * Everything else (locate, printf, putc, cls) will come for free
Steven Cooreman 0:a0faa86660d4 10 *
Steven Cooreman 0:a0faa86660d4 11 * The model is the display will wrap at the right and bottom, so you can
Steven Cooreman 0:a0faa86660d4 12 * keep writing and will always get valid characters. The location is
Steven Cooreman 0:a0faa86660d4 13 * maintained internally to the class to make this easy
Steven Cooreman 0:a0faa86660d4 14 */
Steven Cooreman 0:a0faa86660d4 15
Steven Cooreman 0:a0faa86660d4 16 #ifndef MBED_TEXTDISPLAY_H
Steven Cooreman 0:a0faa86660d4 17 #define MBED_TEXTDISPLAY_H
Steven Cooreman 0:a0faa86660d4 18
Steven Cooreman 0:a0faa86660d4 19 #include "mbed.h"
Steven Cooreman 0:a0faa86660d4 20 #include "LCDSettings.h"
Steven Cooreman 0:a0faa86660d4 21
Steven Cooreman 0:a0faa86660d4 22 class TextDisplay {
Steven Cooreman 0:a0faa86660d4 23 public:
Steven Cooreman 0:a0faa86660d4 24
Steven Cooreman 0:a0faa86660d4 25 // functions needing implementation in derived implementation class
Steven Cooreman 0:a0faa86660d4 26 /** Create a TextDisplay interface
Steven Cooreman 0:a0faa86660d4 27 *
Steven Cooreman 0:a0faa86660d4 28 * @param name The name used in the path to access the strean through the filesystem
Steven Cooreman 0:a0faa86660d4 29 */
Steven Cooreman 0:a0faa86660d4 30 TextDisplay(const char *name = NULL);
Steven Cooreman 0:a0faa86660d4 31
Steven Cooreman 0:a0faa86660d4 32 /** output a character at the given position
Steven Cooreman 0:a0faa86660d4 33 *
Steven Cooreman 0:a0faa86660d4 34 * @param column column where charater must be written
Steven Cooreman 0:a0faa86660d4 35 * @param row where character must be written
Steven Cooreman 0:a0faa86660d4 36 * @param c the character to be written to the TextDisplay
Steven Cooreman 0:a0faa86660d4 37 */
Steven Cooreman 0:a0faa86660d4 38 virtual void character(int column, int row, int c) = 0;
Steven Cooreman 0:a0faa86660d4 39
Steven Cooreman 0:a0faa86660d4 40 /** return number if rows on TextDisplay
Steven Cooreman 0:a0faa86660d4 41 * @result number of rows
Steven Cooreman 0:a0faa86660d4 42 */
Steven Cooreman 0:a0faa86660d4 43 virtual int rows() = 0;
Steven Cooreman 0:a0faa86660d4 44
Steven Cooreman 0:a0faa86660d4 45 /** return number if columns on TextDisplay
Steven Cooreman 0:a0faa86660d4 46 * @result number of rows
Steven Cooreman 0:a0faa86660d4 47 */
Steven Cooreman 0:a0faa86660d4 48 virtual int columns() = 0;
Steven Cooreman 0:a0faa86660d4 49
stevew817 11:0f8ae10b308d 50 // Sets external font usage, eg. dispaly.set_font(Arial12x12);
stevew817 11:0f8ae10b308d 51 // This uses pixel positioning.
stevew817 11:0f8ae10b308d 52 // display.set_font(NULL); returns to internal default font.
stevew817 11:0f8ae10b308d 53 void set_font(const unsigned char * f);
stevew817 11:0f8ae10b308d 54
stevew817 11:0f8ae10b308d 55 // set position of the next character or string print.
stevew817 11:0f8ae10b308d 56 // External font, set pixel x(column),y(row) position.
stevew817 11:0f8ae10b308d 57 // internal(default) font, set character column and row position
stevew817 11:0f8ae10b308d 58 virtual void locate(int column, int row);
stevew817 11:0f8ae10b308d 59
Steven Cooreman 0:a0faa86660d4 60 // functions that come for free, but can be overwritten
Steven Cooreman 0:a0faa86660d4 61
Steven Cooreman 0:a0faa86660d4 62 /** clear screen
Steven Cooreman 0:a0faa86660d4 63 */
Steven Cooreman 0:a0faa86660d4 64 virtual void cls();
Steven Cooreman 0:a0faa86660d4 65 virtual void foreground(uint16_t colour);
Steven Cooreman 0:a0faa86660d4 66 virtual void background(uint16_t colour);
Steven Cooreman 0:a0faa86660d4 67 // putc (from Stream)
Steven Cooreman 0:a0faa86660d4 68 // printf (from Stream)
Steven Cooreman 0:a0faa86660d4 69 virtual void printf(const char* format, ...);
Steven Cooreman 0:a0faa86660d4 70
Steven Cooreman 0:a0faa86660d4 71 protected:
Steven Cooreman 0:a0faa86660d4 72
Steven Cooreman 0:a0faa86660d4 73 virtual int _putc(int value);
Steven Cooreman 0:a0faa86660d4 74 virtual int _getc();
stevew817 11:0f8ae10b308d 75
stevew817 11:0f8ae10b308d 76 // external font functions
stevew817 11:0f8ae10b308d 77 const unsigned char* font;
stevew817 11:0f8ae10b308d 78 int externalfont;
stevew817 11:0f8ae10b308d 79
Steven Cooreman 0:a0faa86660d4 80 // character location
Steven Cooreman 0:a0faa86660d4 81 uint16_t _column;
Steven Cooreman 0:a0faa86660d4 82 uint16_t _row;
stevew817 11:0f8ae10b308d 83 unsigned int char_x;
stevew817 11:0f8ae10b308d 84 unsigned int char_y;
Steven Cooreman 0:a0faa86660d4 85
Steven Cooreman 0:a0faa86660d4 86 // colours
Steven Cooreman 0:a0faa86660d4 87 uint16_t _foreground;
Steven Cooreman 0:a0faa86660d4 88 uint16_t _background;
Steven Cooreman 0:a0faa86660d4 89 char *_path;
Steven Cooreman 0:a0faa86660d4 90 };
Steven Cooreman 0:a0faa86660d4 91
Steven Cooreman 0:a0faa86660d4 92 #endif