A buffered display driver for the SSD1306 OLED controller. Please note that this is a work-in-progress; only very rudimentary drawing support is provided.

Dependents:   Projetv0 greenhouse_proj ProjetLong_Serre_V3 ProjetLong_Serre_V3_1 ... more

Example of use:

#include "mbed.h"

#include "ssd1306.h"
#include "standard_font.h"
#include "bold_font.h"

SSD1306 oled(p8 /* cs */, p9 /* reset */, p14 /* dc */,
             p13 /* clock */, p11 /* data */);

int main()
{
    oled.initialise();
    oled.clear();
    oled.set_contrast(255); // max contrast

    oled.set_font(bold_font, 8);
    oled.printf("Heading\r\n");

    oled.set_font(standard_font, 6);
    oled.printf("Hello World!\r\n");
    oled.printf("Some more text here...");

    oled.update();

    while (1)
    {
        wait(2);
        oled.scroll_up();
        oled.update();
    }
}

Files at this revision

API Documentation at this revision

Comitter:
Byrn
Date:
Sat Feb 09 16:43:49 2013 +0000
Parent:
2:e479b0296757
Commit message:
Completely changed the way fonts work and added printf(), putc() etc. Now only 8 pixel high fonts are supported, but multiple widths. Added auto-scrolling from the bottom of the display. Also replaced the original "smallfont" with two new fonts.

Changed in this revision

bold_font.h Show annotated file Show diff for this revision Revisions of this file
smallfont.h Show diff for this revision Revisions of this file
ssd1306.cpp Show annotated file Show diff for this revision Revisions of this file
ssd1306.h Show annotated file Show diff for this revision Revisions of this file
standard_font.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bold_font.h	Sat Feb 09 16:43:49 2013 +0000
@@ -0,0 +1,109 @@
+/** Thick 8x8 font, good for headings etc. */
+static unsigned char bold_font[] = {
+
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x20] ' '
+    0x0,  0x0,  0x0,  0xDF,  0xDF,  0x0,  0x0,  0x0,    // [0x21] '!'
+    0x0,  0x3,  0x7,  0x0,  0x3,  0x7,  0x0,  0x0,    // [0x22] '"'
+    0x0,  0x14,  0x3E,  0x14,  0x3E,  0x14,  0x0,  0x0,    // [0x23] '#'
+    0x0,  0x24,  0x2A,  0x7F,  0x2A,  0x12,  0x0,  0x0,    // [0x24] '$'
+    0x43,  0x23,  0x10,  0x8,  0x4,  0x62,  0x61,  0x0,    // [0x25] '%'
+    0x38,  0x7C,  0x44,  0x7F,  0x3F,  0x4,  0x4,  0x0,    // [0x26] '&'
+    0x0,  0x0,  0x0,  0x7,  0x7,  0x0,  0x0,  0x0,    // [0x27] '''
+    0x0,  0x0,  0x7E,  0xFF,  0x81,  0x0,  0x0,  0x0,    // [0x28] '('
+    0x0,  0x0,  0x81,  0xFF,  0x7E,  0x0,  0x0,  0x0,    // [0x29] ')'
+    0x8,  0x2A,  0x1C,  0x7F,  0x1C,  0x2A,  0x8,  0x0,    // [0x2A] '*'
+    0x0,  0x8,  0x8,  0x3E,  0x3E,  0x8,  0x8,  0x0,    // [0x2B] '+'
+    0x0,  0x0,  0x80,  0xE0,  0x60,  0x0,  0x0,  0x0,    // [0x2C] ','
+    0x0,  0x8,  0x8,  0x8,  0x8,  0x8,  0x8,  0x0,    // [0x2D] '-'
+    0x0,  0x0,  0x0,  0xC0,  0xC0,  0x0,  0x0,  0x0,    // [0x2E] '.'
+    0x0,  0xC0,  0xF0,  0x3C,  0xF,  0x3,  0x0,  0x0,    // [0x2F] '/'
+    0x3E,  0x7F,  0x51,  0x49,  0x45,  0x7F,  0x3E,  0x0,    // [0x30] '0'
+    0x0,  0x40,  0x42,  0x7F,  0x7F,  0x40,  0x40,  0x0,    // [0x31] '1'
+    0x72,  0x7B,  0x49,  0x49,  0x49,  0x4F,  0x46,  0x0,    // [0x32] '2'
+    0x22,  0x63,  0x41,  0x49,  0x49,  0x7F,  0x36,  0x0,    // [0x33] '3'
+    0x7,  0xF,  0x8,  0x8,  0x8,  0x7E,  0x7E,  0x0,    // [0x34] '4'
+    0x27,  0x6F,  0x49,  0x49,  0x49,  0x79,  0x31,  0x0,    // [0x35] '5'
+    0x3E,  0x7F,  0x49,  0x49,  0x49,  0x79,  0x30,  0x0,    // [0x36] '6'
+    0x1,  0x1,  0x1,  0x1,  0x1,  0x7F,  0x7E,  0x0,    // [0x37] '7'
+    0x36,  0x7F,  0x49,  0x49,  0x49,  0x7F,  0x36,  0x0,    // [0x38] '8'
+    0x6,  0xF,  0x9,  0x9,  0x9,  0x7F,  0x7F,  0x0,    // [0x39] '9'
+    0x0,  0x0,  0x0,  0x63,  0x63,  0x0,  0x0,  0x0,    // [0x3A] ':'
+    0x0,  0x0,  0x80,  0xE3,  0x63,  0x0,  0x0,  0x0,    // [0x3B] ';'
+    0x0,  0x8,  0x1C,  0x36,  0x63,  0x41,  0x0,  0x0,    // [0x3C] '<'
+    0x0,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x0,    // [0x3D] '='
+    0x0,  0x41,  0x63,  0x36,  0x1C,  0x8,  0x0,  0x0,    // [0x3E] '>'
+    0x2,  0x3,  0xD1,  0xD9,  0x9,  0xF,  0x6,  0x0,    // [0x3F] '?'
+    0x3E,  0x7F,  0x41,  0x5D,  0x55,  0x5F,  0xE,  0x0,    // [0x40] '@'
+    0x7E,  0x7F,  0x9,  0x9,  0x9,  0x7F,  0x7E,  0x0,    // [0x41] 'A'
+    0x7F,  0x7F,  0x49,  0x49,  0x49,  0x7F,  0x36,  0x0,    // [0x42] 'B'
+    0x3E,  0x7F,  0x41,  0x41,  0x41,  0x63,  0x22,  0x0,    // [0x43] 'C'
+    0x7F,  0x7F,  0x41,  0x41,  0x63,  0x3E,  0x1C,  0x0,    // [0x44] 'D'
+    0x7F,  0x7F,  0x49,  0x49,  0x49,  0x41,  0x41,  0x0,    // [0x45] 'E'
+    0x7F,  0x7F,  0x9,  0x9,  0x9,  0x1,  0x1,  0x0,    // [0x46] 'F'
+    0x3E,  0x7F,  0x41,  0x49,  0x49,  0x7B,  0x7A,  0x0,    // [0x47] 'G'
+    0x7F,  0x7F,  0x8,  0x8,  0x8,  0x7F,  0x7F,  0x0,    // [0x48] 'H'
+    0x0,  0x41,  0x41,  0x7F,  0x7F,  0x41,  0x41,  0x0,    // [0x49] 'I'
+    0x20,  0x61,  0x41,  0x7F,  0x3F,  0x1,  0x1,  0x0,    // [0x4A] 'J'
+    0x7F,  0x7F,  0x8,  0x1C,  0x36,  0x63,  0x41,  0x0,    // [0x4B] 'K'
+    0x7F,  0x7F,  0x40,  0x40,  0x40,  0x40,  0x40,  0x0,    // [0x4C] 'L'
+    0x7F,  0x7F,  0x6,  0xC,  0x6,  0x7F,  0x7F,  0x0,    // [0x4D] 'M'
+    0x7F,  0x7F,  0x6,  0xC,  0x18,  0x7F,  0x7F,  0x0,    // [0x4E] 'N'
+    0x3E,  0x7F,  0x41,  0x41,  0x41,  0x7F,  0x3E,  0x0,    // [0x4F] 'O'
+    0x7F,  0x7F,  0x9,  0x9,  0x9,  0xF,  0x6,  0x0,    // [0x50] 'P'
+    0x3E,  0x7F,  0x41,  0x61,  0xC1,  0xFF,  0xBE,  0x0,    // [0x51] 'Q'
+    0x7F,  0x7F,  0x9,  0x9,  0x9,  0x7F,  0x76,  0x0,    // [0x52] 'R'
+    0x26,  0x6F,  0x49,  0x49,  0x49,  0x7B,  0x32,  0x0,    // [0x53] 'S'
+    0x0,  0x1,  0x1,  0x7F,  0x7F,  0x1,  0x1,  0x0,    // [0x54] 'T'
+    0x3F,  0x7F,  0x40,  0x40,  0x40,  0x7F,  0x7F,  0x0,    // [0x55] 'U'
+    0x0,  0x7,  0x1F,  0x78,  0x78,  0x1F,  0x7,  0x0,    // [0x56] 'V'
+    0x7F,  0x7F,  0x30,  0x18,  0x30,  0x7F,  0x7F,  0x0,    // [0x57] 'W'
+    0x63,  0x77,  0x1C,  0x8,  0x1C,  0x77,  0x63,  0x0,    // [0x58] 'X'
+    0x27,  0x6F,  0x48,  0x48,  0x48,  0x7F,  0x3F,  0x0,    // [0x59] 'Y'
+    0x61,  0x71,  0x59,  0x4D,  0x47,  0x43,  0x41,  0x0,    // [0x5A] 'Z'
+    0x0,  0x0,  0xFF,  0xFF,  0x81,  0x81,  0x0,  0x0,    // [0x5B] '['
+    0x0,  0x3,  0xF,  0x3C,  0xF0,  0xC0,  0x0,  0x0,    // [0x5C] '\\'
+    0x0,  0x0,  0x81,  0x81,  0xFF,  0xFF,  0x0,  0x0,    // [0x5D] ']'
+    0x4,  0x6,  0x3,  0x1,  0x3,  0x6,  0x4,  0x0,    // [0x5E] '^'
+    0x80,  0x80,  0x80,  0x80,  0x80,  0x80,  0x80,  0x0,    // [0x5F] '_'
+    0x3,  0x7,  0x4,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x60] '`'
+    0x38,  0x7C,  0x44,  0x44,  0x24,  0x7C,  0x78,  0x0,    // [0x61] 'a'
+    0x7F,  0x7F,  0x24,  0x44,  0x44,  0x7C,  0x38,  0x0,    // [0x62] 'b'
+    0x38,  0x7C,  0x44,  0x44,  0x44,  0x44,  0x44,  0x0,    // [0x63] 'c'
+    0x38,  0x7C,  0x44,  0x44,  0x24,  0x7F,  0x7F,  0x0,    // [0x64] 'd'
+    0x38,  0x7C,  0x54,  0x54,  0x54,  0x5C,  0x8,  0x0,    // [0x65] 'e'
+    0x0,  0x4,  0x7E,  0x7F,  0x5,  0x1,  0x0,  0x0,    // [0x66] 'f'
+    0x18,  0xBC,  0xA4,  0xA4,  0x94,  0xFC,  0x78,  0x0,    // [0x67] 'g'
+    0x7F,  0x7F,  0x8,  0x4,  0x4,  0x7C,  0x78,  0x0,    // [0x68] 'h'
+    0x0,  0x0,  0x0,  0x7D,  0x7D,  0x0,  0x0,  0x0,    // [0x69] 'i'
+    0x0,  0x40,  0x40,  0x40,  0x7D,  0x3D,  0x0,  0x0,    // [0x6A] 'j'
+    0x7F,  0x7F,  0x8,  0x8,  0x1C,  0x76,  0x62,  0x0,    // [0x6B] 'k'
+    0x0,  0x0,  0x0,  0x7F,  0x7F,  0x0,  0x0,  0x0,    // [0x6C] 'l'
+    0x78,  0x7C,  0x18,  0x30,  0x18,  0x7C,  0x78,  0x0,    // [0x6D] 'm'
+    0x7C,  0x7C,  0x8,  0x4,  0x4,  0x7C,  0x78,  0x0,    // [0x6E] 'n'
+    0x38,  0x7C,  0x44,  0x44,  0x44,  0x7C,  0x38,  0x0,    // [0x6F] 'o'
+    0xFC,  0xFC,  0x28,  0x24,  0x24,  0x3C,  0x18,  0x0,    // [0x70] 'p'
+    0x1C,  0x1E,  0x22,  0x22,  0x12,  0xFE,  0xFE,  0x0,    // [0x71] 'q'
+    0x7C,  0x7C,  0x8,  0x4,  0x4,  0xC,  0x8,  0x0,    // [0x72] 'r'
+    0x48,  0x5C,  0x54,  0x54,  0x54,  0x74,  0x20,  0x0,    // [0x73] 's'
+    0x3F,  0x7F,  0x44,  0x44,  0x44,  0x60,  0x20,  0x0,    // [0x74] 't'
+    0x3C,  0x7C,  0x40,  0x40,  0x20,  0x7C,  0x7C,  0x0,    // [0x75] 'u'
+    0x0,  0xC,  0x3C,  0x70,  0x70,  0x3C,  0xC,  0x0,    // [0x76] 'v'
+    0x3C,  0x7C,  0x30,  0x18,  0x30,  0x7C,  0x3C,  0x0,    // [0x77] 'w'
+    0x44,  0x6C,  0x38,  0x10,  0x38,  0x6C,  0x44,  0x0,    // [0x78] 'x'
+    0xC,  0x5C,  0x50,  0x50,  0x50,  0x7C,  0x3C,  0x0,    // [0x79] 'y'
+    0x44,  0x64,  0x74,  0x54,  0x5C,  0x4C,  0x44,  0x0,    // [0x7A] 'z'
+    0x0,  0x8,  0x3E,  0x77,  0x41,  0x0,  0x0,  0x0,    // [0x7B] '{'
+    0x0,  0x0,  0x0,  0xFF,  0xFF,  0x0,  0x0,  0x0,    // [0x7C] '|'
+    0x0,  0x41,  0x77,  0x3E,  0x8,  0x0,  0x0,  0x0,    // [0x7D] '}'
+    0x2,  0x3,  0x1,  0x3,  0x2,  0x3,  0x1,  0x0,    // [0x7E] '~'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x7F] ''
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x80] '€'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x81] ''
+    0x0,  0x0,  0x80,  0xE0,  0x60,  0x0,  0x0,  0x0,    // [0x82] '‚'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x83] 'ƒ'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x84] '„'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x85] '…'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x86] '†'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x87] '‡'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x88] 'ˆ'
+};
--- a/smallfont.h	Tue Feb 05 21:21:22 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-
-#ifndef __SMALLFONT_H__
-#define __SMALLFONT_H__
-
-static char smallfont[] = { 
-    0x01, /* Height in bytes */
-    0x06, /* Widest char width (size of char data) */
-    
-    /*
-    width,----------- data -----------------*/
-    0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ' ' (space)
-    0x02, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, // !
-    0x04, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, // "
-    0x06, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x00, // #
-    0x06, 0x02, 0x15, 0x1F, 0x15, 0x08, 0x00, // $
-    0x06, 0x13, 0x09, 0x04, 0x12, 0x19, 0x00, // %
-    0x06, 0x08, 0x14, 0x0F, 0x04, 0x04, 0x00, // &
-    0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // '
-    0x03, 0x1E, 0x21, 0x00, 0x00, 0x00, 0x00, // (
-    0x03, 0x21, 0x1E, 0x00, 0x00, 0x00, 0x00, // )
-    0x06, 0x15, 0x0E, 0x1F, 0x0E, 0x15, 0x00, // *
-    0x04, 0x04, 0x0C, 0x04, 0x00, 0x00, 0x00, // +
-    0x03, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // ,
-    0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, // -
-    0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // .
-    0x06, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // /
-    0x05, 0x0E, 0x11, 0x11, 0x0E, 0x00, 0x00, // 0
-    0x03, 0x02, 0x1F, 0x00, 0x00, 0x00, 0x00, // 1
-    0x05, 0x18, 0x15, 0x15, 0x12, 0x00, 0x00, // 2 
-    0x05, 0x11, 0x15, 0x15, 0x0A, 0x00, 0x00, // 3
-    0x05, 0x0F, 0x08, 0x1E, 0x08, 0x00, 0x00, // 4
-    0x05, 0x17, 0x15, 0x15, 0x09, 0x00, 0x00, // 5
-    0x05, 0x0E, 0x15, 0x15, 0x08, 0x00, 0x00, // 6
-    0x05, 0x01, 0x11, 0x09, 0x07, 0x00, 0x00, // 7
-    0x05, 0x0A, 0x15, 0x15, 0x0A, 0x00, 0x00, // 8
-    0x05, 0x02, 0x05, 0x05, 0x1E, 0x00, 0x00, // 9
-    0x02, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, // :
-    0x03, 0x10, 0x0A, 0x00, 0x00, 0x00, 0x00, // ;
-    0x05, 0x04, 0x0A, 0x11, 0x00, 0x00, 0x00, // <
-    0x04, 0x0A, 0x0A, 0x0A, 0x00, 0x00, 0x00, // =
-    0x05, 0x11, 0x0A, 0x04, 0x00, 0x00, 0x00, // >
-    0x05, 0x01, 0x15, 0x05, 0x02, 0x00, 0x00, // ?
-    0x05, 0x0E, 0x11, 0x15, 0x02, 0x00, 0x00, // @
-    0x05, 0x1E, 0x09, 0x09, 0x1E, 0x00, 0x00, // A
-    0x05, 0x1F, 0x15, 0x15, 0x0A, 0x00, 0x00, // B
-    0x05, 0x0E, 0x11, 0x11, 0x10, 0x00, 0x00, // C
-    0x05, 0x1F, 0x11, 0x11, 0x0E, 0x00, 0x00, // D
-    0x05, 0x1F, 0x15, 0x15, 0x11, 0x00, 0x00, // E
-    0x05, 0x1F, 0x05, 0x05, 0x01, 0x00, 0x00, // F
-    0x05, 0x0E, 0x11, 0x15, 0x1C, 0x00, 0x00, // G
-    0x05, 0x1F, 0x04, 0x04, 0x1F, 0x00, 0x00, // H
-    0x04, 0x11, 0x1F, 0x11, 0x00, 0x00, 0x00, // I
-    0x05, 0x08, 0x11, 0x11, 0x0F, 0x00, 0x00, // J
-    0x05, 0x1F, 0x04, 0x0A, 0x11, 0x00, 0x00, // K
-    0x05, 0x1F, 0x10, 0x10, 0x10, 0x00, 0x00, // L
-    0x06, 0x1F, 0x02, 0x04, 0x02, 0x1F, 0x00, // M
-    0x05, 0x1F, 0x01, 0x01, 0x1E, 0x00, 0x00, // N
-    0x05, 0x0E, 0x11, 0x11, 0x0E, 0x00, 0x00, // O
-    0x05, 0x1F, 0x05, 0x05, 0x02, 0x00, 0x00, // P
-    0x06, 0x0E, 0x11, 0x19, 0x1E, 0x20, 0x00, // Q
-    0x05, 0x1F, 0x05, 0x05, 0x1A, 0x00, 0x00, // R
-    0x05, 0x12, 0x15, 0x15, 0x08, 0x00, 0x00, // S
-    0x04, 0x01, 0x1F, 0x01, 0x00, 0x00, 0x00, // T
-    0x05, 0x0F, 0x10, 0x10, 0x1F, 0x00, 0x00, // U
-    0x06, 0x07, 0x08, 0x10, 0x08, 0x07, 0x00, // V
-    0x06, 0x1F, 0x08, 0x04, 0x08, 0x1F, 0x00, // W
-    0x06, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x00, // X
-    0x05, 0x03, 0x14, 0x14, 0x0F, 0x00, 0x00, // Y
-    0x05, 0x19, 0x15, 0x13, 0x11, 0x00, 0x00, // Z
-    0x03, 0x3F, 0x21, 0x00, 0x00, 0x00, 0x00, // [
-    0x06, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00, // \\
-    0x01, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, // ?
-    0x03, 0x21, 0x3F, 0x00, 0x00, 0x00, 0x00, // ]
-    0x04, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, // ^
-    0x05, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, // _
-    0x03, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, // `
-    0x05, 0x0C, 0x12, 0x12, 0x1C, 0x00, 0x00, // a
-    0x05, 0x1F, 0x12, 0x12, 0x0C, 0x00, 0x00, // b
-    0x05, 0x0C, 0x12, 0x12, 0x12, 0x00, 0x00, // c
-    0x05, 0x0C, 0x12, 0x12, 0x1F, 0x00, 0x00, // d
-    0x05, 0x0E, 0x15, 0x15, 0x02, 0x00, 0x00, // e
-    0x05, 0x04, 0x3E, 0x05, 0x01, 0x00, 0x00, // f
-    0x05, 0x0C, 0x2A, 0x2A, 0x1E, 0x00, 0x00, // g
-    0x05, 0x1F, 0x02, 0x02, 0x1A, 0x00, 0x00, // h
-    0x02, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, // i
-    0x04, 0x20, 0x20, 0x1D, 0x00, 0x00, 0x00, // j
-    0x04, 0x1F, 0x04, 0x1A, 0x00, 0x00, 0x00, // k
-    0x02, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, // l
-    0x06, 0x1C, 0x02, 0x0C, 0x02, 0x1C, 0x00, // m
-    0x05, 0x1E, 0x02, 0x02, 0x1C, 0x00, 0x00, // n
-    0x05, 0x0C, 0x12, 0x12, 0x0C, 0x00, 0x00, // o
-    0x05, 0x3E, 0x12, 0x12, 0x0C, 0x00, 0x00, // p
-    0x05, 0x0C, 0x12, 0x12, 0x3E, 0x00, 0x00, // q
-    0x05, 0x1C, 0x02, 0x02, 0x00, 0x00, 0x00, // r
-    0x05, 0x12, 0x15, 0x15, 0x08, 0x00, 0x00, // s
-    0x05, 0x02, 0x0F, 0x12, 0x02, 0x00, 0x00, // t
-    0x05, 0x0E, 0x10, 0x10, 0x1F, 0x00, 0x00, // u
-    0x04, 0x0C, 0x10, 0x0C, 0x00, 0x00, 0x00, // v
-    0x06, 0x0C, 0x10, 0x0A, 0x10, 0x0C, 0x00, // w
-    0x05, 0x12, 0x0C, 0x0C, 0x12, 0x00, 0x00, // x
-};
-
-#endif
--- a/ssd1306.cpp	Tue Feb 05 21:21:22 2013 +0000
+++ b/ssd1306.cpp	Sat Feb 09 16:43:49 2013 +0000
@@ -2,11 +2,15 @@
 #include "mbed.h"
 #include "ssd1306.h"
 
+#include <stdarg.h>
+
 SSD1306::SSD1306(PinName cs, PinName rs, PinName dc, PinName clk, PinName data)
     : _spi(data, NC, clk), 
       _cs(cs), 
       _reset(rs), 
-      _dc(dc)
+      _dc(dc),
+      _cursor_x(0),
+      _cursor_y(0)
 {
 }
 
@@ -211,7 +215,7 @@
     set_display_offset(0);    
     set_display_start_line(0);  
     set_charge_pump_enable(1);    
-    set_memory_addressing_mode(0); // horizontal addressing mode
+    set_memory_addressing_mode(0); // horizontal addressing mode; across then down
     set_segment_remap(1);
     set_com_output_scan_direction(1);
     set_com_pins_hardware_configuration(1, 0);
@@ -294,32 +298,95 @@
   }
 }
 
-void SSD1306::draw_string(char *font, int x, int y, const char *string)
+void SSD1306::set_font(unsigned char *font, unsigned int width)
 {
-    _cursor_x = x;
-    _cursor_y = y;
-    
-    for (int i = 0; i < strlen(string); i++) 
-        draw_char(font, _cursor_x, _cursor_y, string[i]);
+    _console_font_data = font;
+    _console_font_width = width;
+}
+
+void SSD1306::set_double_height_text(unsigned int double_height)
+{
+    _double_height_text = double_height;
 }
 
-void SSD1306::draw_char(char *font, int x, int y, char c)
+void SSD1306::putc(unsigned char c)
 {
-    int height = font[FONT_HEIGHT_OFFSET];
-    int max_width = font[FONT_SIZE_OFFSET];
-    int char_size_bytes = max_width * height + 1;
-    int char_width = font[(c - FONT_START) * char_size_bytes + FONT_DATA_OFFSET];
-    for (int i = 0; i < char_width; i++)
-        _screen[(x + i) + (y * SSD1306_LCDWIDTH)] = font[(c - FONT_START) * (char_size_bytes) + i + FONT_DATA_OFFSET + 1];
+    while (_cursor_x >= (128 / _console_font_width))
+    {
+        _cursor_x -= (128 / _console_font_width);
+        _cursor_y++;            
+    }
+
+    while (_cursor_y > 7)
+    {
+        scroll_up();            
+    }
+
+    switch (c)
+    {
+    case '\n':
+        _cursor_y++;
+        break;
+        
+    case '\r':
+        _cursor_x = 0;
+        break;
+        
+    case '\t':
+        _cursor_x = (_cursor_x + 4) % 4;
+        break;
+        
+    default:
+        for (int b = 0; b < _console_font_width; b++)
+        {
+            _screen[_cursor_x * _console_font_width + _cursor_y * 128 + b] = _console_font_data[(c - FONT_START) * _console_font_width + b];
+        }
+        
+        _cursor_x++;
+    }            
+}
+
+void SSD1306::scroll_up()
+{
+    for (int y = 1; y <= 7; y++)
+    {
+        for (int x = 0; x < 128; x++)
+        {
+            _screen[x + 128 * (y - 1)] = _screen[x + 128 * y];
+        }
+    }
     
-    _cursor_x = x + char_width;
-    _cursor_y = y;
+    for (int x = 0; x < 128; x++)
+    {
+        _screen[x + 128 * 7] = 0;
+    }    
+
+    _cursor_y--;
+}
+
+void SSD1306::printf(const char *format, ...)
+{
+    static char buffer[128];
+    
+    va_list args;
+    va_start(args, format);
+    vsprintf(buffer, format, args);
+    va_end(args);
+    
+    char *c = (char *)&buffer;
+    while (*c != 0)
+    {
+        putc(*c++);
+    }
 }
 
 void SSD1306::clear()
 {
     for (int i = 0; i < 1024; i++)
         _screen[i] = 0;
+        
+    _cursor_x = 0;
+    _cursor_y = 0;
 }
 
 void SSD1306::_send_command(unsigned char code)
--- a/ssd1306.h	Tue Feb 05 21:21:22 2013 +0000
+++ b/ssd1306.h	Sat Feb 09 16:43:49 2013 +0000
@@ -1,16 +1,22 @@
 #ifndef __SSD1306_H__
 #define __SSD1306_H__
 
-#define FONT_HEIGHT_OFFSET  0    /* Character pixel height (in multiples of 8) at this position */
-#define FONT_SIZE_OFFSET    1    /* Character data size (in bytes) at this position */
-#define FONT_DATA_OFFSET    2    /* Data starts at this position */
 #define FONT_START          ' '  /* First character value in the font table */
 
 /** SSD1306 Controller Driver
- *
- * Information taken from the datasheet at:
- *   http://www.adafruit.com/datasheets/SSD1306.pdf
- */
+  *
+  * This class provides a buffered display for the SSD1306 OLED controller.
+  * 
+  * TODO: 
+  *   - At the moment, the driver assumes a 128x64 pixel display.
+  *   - Only fonts of 8 pixel height are supported (different widths can be used).
+  *   - Pretty much no drawing functions are provided as yet.
+  *   - Possible "auto-update", automatically calling update() after a printf etc.
+  *
+  * Information taken from the datasheet at:
+  *   http://www.adafruit.com/datasheets/SSD1306.pdf
+  *
+  */
 class SSD1306
 {
 public:
@@ -180,8 +186,34 @@
     void clear_pixel(int x, int y);
     void line(int x0, int y0, int x1, int y1);
 
-    void draw_string(char *font, int x, int y, const char *string);
-    void draw_char(char *font, int x, int y, char c);
+    /** Set the current console font.
+      * @param font Font data, layed out vertically!
+      * @param width Width of the font characters in pixels.
+      * Fonts are always (at present) 8 pixels in height.
+      */
+    void set_font(unsigned char *font, unsigned int width);
+    
+    /** Set double height text output.
+      * @param double_height If 1, calls to putc(), printf() etc will
+      * result in text taking up 2 lines instead of 1.
+      */
+    void set_double_height_text(unsigned int double_height);
+    
+    /** Put a single character to the screen buffer.
+      * Repeated calls to putc() will cause the cursor to move across and
+      * then down as needed, with scrolling.
+      * @param c The character to write.
+      */
+    void putc(unsigned char c);
+    
+    /** Print to the screen buffer.
+      * printf() will wrap and scroll the screen as needed to display the text given.
+      * @param format Format specifier, same as printf() in normal C.
+      */
+    void printf(const char *format, ...);
+
+    /** Scroll the screen buffer up by one line. */
+    void scroll_up();
 
 private:
     SPI _spi;
@@ -192,6 +224,10 @@
 
     void _send_command(unsigned char code);
     void _send_data(unsigned char value);
+    
+    unsigned char *_console_font_data;  
+    unsigned int _console_font_width;
+    unsigned int _double_height_text;
 };
 
 #define SSD1306_LCDWIDTH 128
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/standard_font.h	Sat Feb 09 16:43:49 2013 +0000
@@ -0,0 +1,112 @@
+/** Thin 5x8 font. */
+static unsigned char standard_font[] = {
+
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x20] ' '
+    0x0,  0x0,  0x2F,  0x0,  0x0,  0x0,    // [0x21] '!'
+    0x0,  0x3,  0x0,  0x3,  0x0,  0x0,    // [0x22] '"'
+    0x14,  0x3E,  0x14,  0x3E,  0x14,  0x0,    // [0x23] '#'
+    0x24,  0x2A,  0x7F,  0x2A,  0x12,  0x0,    // [0x24] '$'
+    0x22,  0x10,  0x8,  0x4,  0x22,  0x0,    // [0x25] '%'
+    0x18,  0x24,  0x24,  0x1E,  0x4,  0x0,    // [0x26] '&'
+    0x0,  0x0,  0x3,  0x0,  0x0,  0x0,    // [0x27] '''
+    0x0,  0x1C,  0x22,  0x41,  0x0,  0x0,    // [0x28] '('
+    0x0,  0x41,  0x22,  0x1C,  0x0,  0x0,    // [0x29] ')'
+    0x2A,  0x1C,  0x3E,  0x1C,  0x2A,  0x0,    // [0x2A] '*'
+    0x8,  0x8,  0x3E,  0x8,  0x8,  0x0,    // [0x2B] '+'
+    0x0,  0x40,  0x20,  0x0,  0x0,  0x0,    // [0x2C] ','
+    0x8,  0x8,  0x8,  0x8,  0x8,  0x0,    // [0x2D] '-'
+    0x0,  0x0,  0x20,  0x0,  0x0,  0x0,    // [0x2E] '.'
+    0x0,  0xC0,  0x30,  0xC,  0x3,  0x0,    // [0x2F] '/'
+    0x1E,  0x29,  0x2D,  0x25,  0x1E,  0x0,    // [0x30] '0'
+    0x0,  0x22,  0x3F,  0x20,  0x0,  0x0,    // [0x31] '1'
+    0x32,  0x29,  0x29,  0x29,  0x26,  0x0,    // [0x32] '2'
+    0x12,  0x21,  0x29,  0x29,  0x16,  0x0,    // [0x33] '3'
+    0x7,  0x8,  0x8,  0x8,  0x3E,  0x0,    // [0x34] '4'
+    0x17,  0x25,  0x25,  0x25,  0x18,  0x0,    // [0x35] '5'
+    0x1E,  0x25,  0x25,  0x25,  0x18,  0x0,    // [0x36] '6'
+    0x1,  0x1,  0x9,  0x9,  0x3E,  0x0,    // [0x37] '7'
+    0x1A,  0x25,  0x25,  0x25,  0x1A,  0x0,    // [0x38] '8'
+    0x6,  0x9,  0x9,  0x9,  0x3E,  0x0,    // [0x39] '9'
+    0x0,  0x0,  0x22,  0x0,  0x0,  0x0,    // [0x3A] ':'
+    0x0,  0x40,  0x22,  0x0,  0x0,  0x0,    // [0x3B] ';'
+    0x0,  0x8,  0x14,  0x22,  0x41,  0x0,    // [0x3C] '<'
+    0x14,  0x14,  0x14,  0x14,  0x14,  0x0,    // [0x3D] '='
+    0x0,  0x41,  0x22,  0x14,  0x8,  0x0,    // [0x3E] '>'
+    0x2,  0x1,  0x29,  0x9,  0x6,  0x0,    // [0x3F] '?'
+    0x1E,  0x21,  0x2D,  0x2D,  0x6,  0x0,    // [0x40] '@'
+    0x3E,  0x11,  0x11,  0x11,  0x3E,  0x0,    // [0x41] 'A'
+    0x3E,  0x25,  0x25,  0x25,  0x1A,  0x0,    // [0x42] 'B'
+    0x1E,  0x21,  0x21,  0x21,  0x12,  0x0,    // [0x43] 'C'
+    0x3E,  0x21,  0x21,  0x22,  0x1C,  0x0,    // [0x44] 'D'
+    0x3F,  0x29,  0x29,  0x21,  0x21,  0x0,    // [0x45] 'E'
+    0x3F,  0x9,  0x9,  0x1,  0x1,  0x0,    // [0x46] 'F'
+    0x1E,  0x21,  0x29,  0x29,  0x1A,  0x0,    // [0x47] 'G'
+    0x3F,  0x8,  0x8,  0x8,  0x3F,  0x0,    // [0x48] 'H'
+    0x0,  0x21,  0x3F,  0x21,  0x0,  0x0,    // [0x49] 'I'
+    0x10,  0x20,  0x21,  0x21,  0x1F,  0x0,    // [0x4A] 'J'
+    0x3F,  0x8,  0xC,  0x12,  0x21,  0x0,    // [0x4B] 'K'
+    0x1F,  0x20,  0x20,  0x20,  0x20,  0x0,    // [0x4C] 'L'
+    0x3E,  0x1,  0x6,  0x1,  0x3E,  0x0,    // [0x4D] 'M'
+    0x3E,  0x1,  0x1,  0x2,  0x3C,  0x0,    // [0x4E] 'N'
+    0x1E,  0x21,  0x21,  0x21,  0x1E,  0x0,    // [0x4F] 'O'
+    0x3E,  0x11,  0x11,  0x11,  0xE,  0x0,    // [0x50] 'P'
+    0x1E,  0x21,  0x29,  0x71,  0x5E,  0x0,    // [0x51] 'Q'
+    0x3E,  0x9,  0x9,  0x9,  0x36,  0x0,    // [0x52] 'R'
+    0x12,  0x25,  0x25,  0x25,  0x18,  0x0,    // [0x53] 'S'
+    0x1,  0x1,  0x3F,  0x1,  0x1,  0x0,    // [0x54] 'T'
+    0x1F,  0x20,  0x20,  0x20,  0x1F,  0x0,    // [0x55] 'U'
+    0xF,  0x10,  0x20,  0x10,  0xF,  0x0,    // [0x56] 'V'
+    0x1F,  0x20,  0x18,  0x20,  0x1F,  0x0,    // [0x57] 'W'
+    0x31,  0xA,  0x4,  0xA,  0x31,  0x0,    // [0x58] 'X'
+    0x7,  0x28,  0x28,  0x28,  0x1F,  0x0,    // [0x59] 'Y'
+    0x31,  0x29,  0x25,  0x23,  0x21,  0x0,    // [0x5A] 'Z'
+    0x0,  0x7F,  0x41,  0x41,  0x0,  0x0,    // [0x5B] '['
+    0x0,  0x3,  0xC,  0x30,  0xC0,  0x0,    // [0x5C] '\\'
+    0x0,  0x41,  0x41,  0x7F,  0x0,  0x0,    // [0x5D] ']'
+    0x0,  0x2,  0x1,  0x2,  0x0,  0x0,    // [0x5E] '^'
+    0x40,  0x40,  0x40,  0x40,  0x40,  0x0,    // [0x5F] '_'
+    0x1,  0x2,  0x0,  0x0,  0x0,  0x0,    // [0x60] '`'
+    0x1C,  0x22,  0x22,  0x22,  0x3C,  0x0,    // [0x61] 'a'
+    0x1F,  0x22,  0x22,  0x22,  0x1C,  0x0,    // [0x62] 'b'
+    0x1C,  0x22,  0x22,  0x22,  0x20,  0x0,    // [0x63] 'c'
+    0x1C,  0x22,  0x22,  0x22,  0x1F,  0x0,    // [0x64] 'd'
+    0x1C,  0x2A,  0x2A,  0x2A,  0x4,  0x0,    // [0x65] 'e'
+    0x8,  0x7E,  0x9,  0x1,  0x1,  0x0,    // [0x66] 'f'
+    0xC,  0x52,  0x52,  0x52,  0x3C,  0x0,    // [0x67] 'g'
+    0x3F,  0x2,  0x2,  0x2,  0x3C,  0x0,    // [0x68] 'h'
+    0x0,  0x0,  0x3D,  0x0,  0x0,  0x0,    // [0x69] 'i'
+    0x20,  0x40,  0x40,  0x40,  0x3D,  0x0,    // [0x6A] 'j'
+    0x3F,  0x8,  0x8,  0x14,  0x22,  0x0,    // [0x6B] 'k'
+    0x0,  0x1F,  0x20,  0x20,  0x0,  0x0,    // [0x6C] 'l'
+    0x3C,  0x2,  0x4,  0x2,  0x3C,  0x0,    // [0x6D] 'm'
+    0x3C,  0x2,  0x2,  0x2,  0x3C,  0x0,    // [0x6E] 'n'
+    0x1C,  0x22,  0x22,  0x22,  0x1C,  0x0,    // [0x6F] 'o'
+    0x7C,  0x12,  0x12,  0x12,  0xC,  0x0,    // [0x70] 'p'
+    0xC,  0x12,  0x12,  0x12,  0x7E,  0x0,    // [0x71] 'q'
+    0x3C,  0x2,  0x2,  0x2,  0x4,  0x0,    // [0x72] 'r'
+    0x24,  0x2A,  0x2A,  0x2A,  0x10,  0x0,    // [0x73] 's'
+    0x1F,  0x22,  0x22,  0x20,  0x10,  0x0,    // [0x74] 't'
+    0x1E,  0x20,  0x20,  0x20,  0x1E,  0x0,    // [0x75] 'u'
+    0xE,  0x10,  0x20,  0x10,  0xE,  0x0,    // [0x76] 'v'
+    0x1E,  0x20,  0x10,  0x20,  0x1E,  0x0,    // [0x77] 'w'
+    0x22,  0x14,  0x8,  0x14,  0x22,  0x0,    // [0x78] 'x'
+    0xE,  0x50,  0x50,  0x50,  0x3E,  0x0,    // [0x79] 'y'
+    0x22,  0x32,  0x2A,  0x26,  0x22,  0x0,    // [0x7A] 'z'
+    0x0,  0x8,  0x36,  0x41,  0x0,  0x0,    // [0x7B] '{'
+    0x0,  0x0,  0x7F,  0x0,  0x0,  0x0,    // [0x7C] '|'
+    0x0,  0x41,  0x36,  0x8,  0x0,  0x0,    // [0x7D] '}'
+    0x0,  0x2,  0x1,  0x2,  0x1,  0x0,    // [0x7E] '~'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x7F] ''
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x80] '€'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x81] ''
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x82] '‚'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x83] 'ƒ'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x84] '„'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x85] '…'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x86] '†'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x87] '‡'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x88] 'ˆ'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x89] '‰'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x8A] 'Š'
+    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,    // [0x8B] '‹'
+};