This includes all known improvements from other people's spins on the Nokia library, including Alistair Popple's fix to the very poor contrast on newer LCD 6100 displays.

Fork of NokiaLCD by Iftekhar Choudhury

Revision:
0:ff874f85ed33
Child:
1:8f005b0dcfa7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NokiaLCD.cpp	Wed Jun 09 08:02:04 2010 +0000
@@ -0,0 +1,367 @@
+/* mbed Nokia LCD Library
+ * Copyright (c) 2007-2010, sford
+ */
+
+#include "NokiaLCD.h"
+
+#include "mbed.h"
+
+#define NOKIALCD_ROWS 16
+#define NOKIALCD_COLS 16
+#define NOKIALCD_WIDTH 130
+#define NOKIALCD_HEIGHT 130
+#define NOKIALCD_FREQUENCY 5000000
+
+NokiaLCD::NokiaLCD(PinName mosi, PinName sclk, PinName cs, PinName rst, LCDType type)
+        : _spi(mosi, NC, sclk)
+        , _rst(rst)
+        , _cs(cs) {
+
+    _type = type;
+
+    _row = 0;
+    _column = 0;
+    _foreground = 0x00FFFFFF;
+    _background = 0x00000000;
+
+    reset();
+}
+
+void NokiaLCD::reset() {
+
+    // setup the SPI interface and bring display out of reset
+    _cs = 1;
+    _rst = 0;
+    _spi.format(9);
+    _spi.frequency(NOKIALCD_FREQUENCY);
+    wait_ms(1);
+    _rst = 1;
+    wait_ms(1);
+
+    _cs = 0;
+
+    switch (_type) {
+        case LCD6100:
+            command(0xCA); // display control
+            data(0);
+            data(32);
+            data(0);
+            command(0xBB);
+            data(1);
+            command(0xD1); // oscillator on
+            command(0x94); // sleep out
+            command(0x20); // power control
+            data(0x0F);
+            command(0xA7); // invert display
+            command(0x81); // Voltage control
+            data(39);      // contrast setting: 0..63
+            data(3);       // resistance ratio
+            wait_ms(1);
+            command(0xBC);
+            data(0);
+            data(1);
+            data(4);
+            command(0xAF);  // turn on the display
+            break;
+            
+        case LCD6610:
+            command(0xCA);    // display control
+            data(0);
+            data(31);
+            data(0);
+            command(0xBB);
+            data(1);
+            command(0xD1); // oscillator on
+            command(0x94); // sleep out
+            command(0x20); // power control
+            data(0x0F);
+            command(0xA7); // invert display
+            command(0x81); // Voltage control
+            data(39);      // contrast setting: 0..63
+            data(3);       // resistance ratio
+            wait_ms(1);
+            command(0xBC);
+            data(0);
+            data(0);
+            data(2);
+            command(0xAF);  // turn on the display
+            break;
+            
+        case PCF8833:
+            command(0x11);  // sleep out
+            command(0x3A);  // column mode
+            data(0x05);
+            command(0x36);  // madctl
+            data(0x60);     // vertical RAM, flip x
+            command(0x25);  // setcon
+            data(0x30);// contrast 0x30
+            wait_ms(2);
+            command(0x29);//DISPON
+            command(0x03);//BSTRON
+            break;
+    }
+
+    _cs = 1;
+
+    cls();
+}
+
+void NokiaLCD::command(int value) {
+    _spi.write(value & 0xFF);
+}
+
+void NokiaLCD::data(int value) {
+    _spi.write(value | 0x100);
+}
+
+void NokiaLCD::_window(int x, int y, int width, int height) {
+    int x1 = x + 2;
+    int y1 = y + 0;
+    int x2 = x1 + width - 1;
+    int y2 = y1 + height - 1;
+
+    switch (_type) {
+        case LCD6100:
+        case LCD6610:
+            command(0x15); // column
+            data(x1);
+            data(x2);
+            command(0x75); // row
+            data(y1);
+            data(y2);
+            command(0x5C); // start write to ram
+            break;
+        case PCF8833:
+            command(0x2A);  // column
+            data(x1);
+            data(x2);
+            command(0x2B); // row
+            data(y1);
+            data(y2);
+            command(0x2C); // start write to ram
+            break;
+    }
+}
+
+void NokiaLCD::_putp(int colour) {
+    int gr = ((colour >> 20) & 0x0F)
+             | ((colour >> 8 ) & 0xF0);
+    int nb = ((colour >> 4 ) & 0x0F);
+    data(nb);
+    data(gr);
+}
+
+const unsigned char FONT8x8[97][8] = {
+    0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
+    0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // !
+    0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // "
+    0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // #
+    0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $
+    0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00, // %
+    0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00, // &
+    0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00, // '
+    0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // (
+    0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // )
+    0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // *
+    0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00, // +
+    0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // ,
+    0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // -
+    0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // .
+    0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash)
+    0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30
+    0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1
+    0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2
+    0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3
+    0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00, // 4
+    0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00, // 5
+    0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00, // 6
+    0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00, // 7
+    0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00, // 8
+    0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00, // 9
+    0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // :
+    0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ;
+    0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00, // <
+    0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // =
+    0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00, // >
+    0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00, // ?
+    0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00, // @ 0x40
+    0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00, // A
+    0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00, // B
+    0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00, // C
+    0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00, // D
+    0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00, // E
+    0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00, // F
+    0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00, // G
+    0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00, // H
+    0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I
+    0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // J
+    0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00, // K
+    0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00, // L
+    0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00, // M
+    0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00, // N
+    0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00, // O
+    0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00, // P 0x50
+    0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00, // Q
+    0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00, // R
+    0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00, // S
+    0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00, // T
+    0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, // U
+    0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00, // V
+    0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, // W
+    0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00, // X
+    0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y
+    0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00, // Z
+    0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [
+    0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // \ (back slash)
+    0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ]
+    0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, // ^
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _
+    0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ` 0x60
+    0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00, // a
+    0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00, // b
+    0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00, // c
+    0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00, // d
+    0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, // e
+    0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00, // f
+    0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C, // g
+    0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00, // h
+    0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i
+    0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j
+    0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00, // k
+    0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l
+    0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, // m
+    0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00, // n
+    0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, // o
+    0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78, // p
+    0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F, // q
+    0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00, // r
+    0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, // s
+    0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00, // t
+    0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00, // u
+    0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00, // v
+    0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00, // w
+    0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00, // x
+    0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C, // y
+    0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z
+    0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // {
+    0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // |
+    0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // }
+    0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~
+    0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00
+}; // DEL
+
+void NokiaLCD::locate(int column, int row) {
+    _column = column;
+    _row = row;
+}
+
+void NokiaLCD::newline() {
+    _column = 0;
+    _row++;
+    if (_row >= _rows) {
+        _row = 0;
+    }
+}
+
+int NokiaLCD::_putc(int value) {
+    int x = _column * 8;  // FIXME: Char sizes
+    int y = _row * 8;
+    bitblit(x + 1, y + 1, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
+
+    _column++;
+
+    if (_column >= NOKIALCD_COLS) {
+        _row++;
+        _column = 0;
+    }
+
+    if (_row >= NOKIALCD_ROWS) {
+        _row = 0;
+    }
+
+    return value;
+}
+
+void NokiaLCD::cls() {
+    fill(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT, _background);
+    _row = 0;
+    _column = 0;
+}
+
+
+void NokiaLCD::window(int x, int y, int width, int height) {
+    _cs = 0;
+    _window(x, y, width, height);
+    _cs = 1;
+}
+
+void NokiaLCD::putp(int colour) {
+    _cs = 0;
+    _putp(colour);
+    _cs = 1;
+}
+
+void NokiaLCD::pixel(int x, int y, int colour) {
+    _cs = 0;
+    _window(x, y, 1, 1);
+    _putp(colour);
+    _cs = 1;
+}
+
+void NokiaLCD::fill(int x, int y, int width, int height, int colour) {
+    _cs = 0;
+    _window(x, y, width, height);
+    for (int i=0; i<width*height; i++) {
+        _putp(colour);
+    }
+    _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
+    _cs = 1;
+}
+
+void NokiaLCD::blit(int x, int y, int width, int height, const int* colour) {
+    _cs = 0;
+    _window(x, y, width, height);
+    for (int i=0; i<width*height; i++) {
+        _putp(colour[i]);
+    }
+    _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
+    _cs = 1;
+}
+
+void NokiaLCD::bitblit(int x, int y, int width, int height, const char* bitstream) {
+    _cs = 0;
+    _window(x, y, width, height);
+    for (int i=0; i<height*width; i++) {
+        int byte = i / 8;
+        int bit = i % 8;
+        int colour = ((bitstream[byte] << bit) & 0x80) ? _foreground : _background;
+        _putp(colour);
+    }
+    _window(0, 0, _width, _height);
+    _cs = 1;
+}
+
+void NokiaLCD::foreground(int c) {
+    _foreground = c;
+}
+
+void NokiaLCD::background(int c) {
+    _background = c;
+}
+
+int NokiaLCD::width() {
+    return NOKIALCD_WIDTH;
+}
+
+int NokiaLCD::height() {
+    return NOKIALCD_HEIGHT;
+}
+
+int NokiaLCD::columns() {
+    return NOKIALCD_COLS;
+}
+
+int NokiaLCD::rows() {
+    return NOKIALCD_ROWS;
+}