This library provides an OLED (SSD1332, 96x64xRGB) interface that best utilizes SSD1332's graphic accelerator (especially for drawing lines and rectangles). Though it still has some limitations --- it does not support 'clipping', odd numbers for circle/ellipse diameter, and so on, it runs quite fast. Enjoy the speed.

Dependents:   OLEDexample

Fork of OLEDaccel by Hideki Kozima

Files at this revision

API Documentation at this revision

Comitter:
xkozima
Date:
Fri Aug 17 15:30:29 2012 +0000
Commit message:
This library provides an OLED (SSD1332, 96x64xRGB) interface that best utilizes SSD1332's graphic accelerator (especially for drawing lines and rectangles). Though it still has some limitations --- it does not support 'clipping', odd numbers for circle...

Changed in this revision

OLEDaccel.cpp Show annotated file Show diff for this revision Revisions of this file
OLEDaccel.h Show annotated file Show diff for this revision Revisions of this file
font6x8.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 76a5ae915f62 OLEDaccel.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OLEDaccel.cpp	Fri Aug 17 15:30:29 2012 +0000
@@ -0,0 +1,400 @@
+//
+//  OLEDaccel: 96x64 OLED driver
+//  (version 0.2, August 17, 2012)
+//  xkozima@myu.ac.jp
+
+#include "OLEDaccel.h"  
+#include "font6x8.h"                                                          
+
+OLED::OLED (PinName rstPin, PinName csPin, PinName dcPin, PinName mosiPin, PinName sckPin) :
+    rst(rstPin), cs(csPin), dc(dcPin), spi(mosiPin, NC, sckPin)
+{
+    //  setup spi (8bit master @48MHz)                                          
+    spi.format(8,3);
+    spi.frequency(48000000);
+    wait_ms(20);
+
+    //  reset OLED                                                              
+    rst = 0;
+    wait_ms(20);
+    rst = 1;
+    wait_ms(20);
+
+    //  init command
+    unsigned char cmd1[] = {0xa0, 0x70};
+    cmdOut(cmd1, 2);
+    unsigned char cmd2[] = {0xaf};
+    cmdOut(cmd2, 1);
+    unsigned char cmd3[] = {0x26, 0x01};
+    cmdOut(cmd3, 2);
+    
+    //  clear flags
+    reversal = false;
+    filling = true;
+
+    //  clear and display on
+    rect(0, 0, 96, 64, 0, 1);
+    wait(0.1);
+    cmdOutOne(0xaf);    //  display on
+}
+
+void  OLED::cmdOutOne(unsigned char cmdOne)
+{
+     dc = 0;
+     cs = 0;
+     spi.write(cmdOne);
+     cs = 1;
+}
+
+void  OLED::cmdOut(unsigned char *cmd, int length)
+{
+     dc = 0;
+     cs = 0;
+     for (int i = 0; i < length; i++) {
+        spi.write(*cmd++);
+     }
+     cs = 1;
+}
+
+void  OLED::dataOut(unsigned short *data, int length)
+{
+     dc = 1;
+     cs = 0;
+     for (int i = 0; i < length; i++) {
+        unsigned short d16 = *data++;
+        spi.write((unsigned char) ((d16 & 0xff00) >> 8));
+        spi.write((unsigned char) (d16 & 0x00ff));
+     }
+     cs = 1;
+}
+
+unsigned short OLED::color (int r, int g, int b)
+{
+    return ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3);
+}
+
+void OLED::clear (unsigned short color)
+{
+    rect(0, 0, 96, 64, color, 1);
+}
+
+void OLED::point(int x, int y, unsigned short color)
+{
+    //  draw a point (a small rectangle/filled)
+    unsigned char c1 = (color & 0xf800) >> 10, 
+                  c2 = (color & 0x07e0) >> 5, 
+                  c3 = (color & 0x001f) << 1;
+    unsigned char cmd[] = {0x22, x, y, x, y,  
+                           c1, c2, c3,  c1, c2, c3 };
+    cmdOut(cmd, 11);
+}
+
+void OLED::rect (int x, int y, int w, int h,
+                 unsigned short color, int fill )
+{
+    unsigned char c1 = (color & 0xf800) >> 10, 
+                  c2 = (color & 0x07e0) >> 5, 
+                  c3 = (color & 0x001f) << 1;
+    //  
+    //  fill or no fill
+    if (fill) {
+        if (! filling) {
+            unsigned char cmdF[] = {0x26, 1};
+            cmdOut(cmdF, 2); 
+            filling = true;     
+        }
+    }
+    else {
+        if (filling) {
+            unsigned char cmdN[] = {0x26, 0};
+            cmdOut(cmdN, 2);
+            filling = false;
+        }
+    }
+    //  un-reverse
+    if (reversal) {
+        unsigned char cmdN[] = {0xa0, 0x70};
+        cmdOut(cmdN, 2);
+        reversal = false;
+    }
+    //  draw/fill the rectangle
+    unsigned char cmd[] = {0x22, x, y, x + w - 1, y + h - 1, 
+                           c1, c2, c3,  c1, c2, c3 };
+    cmdOut(cmd, 11);
+    //  wait
+    wait_us(w * h / 10);
+}
+
+void OLED::line(int x1, int y1, int x2, int y2, unsigned short color)
+{
+    unsigned char c1 = (color & 0xf800) >> 10, 
+                  c2 = (color & 0x07e0) >> 5, 
+                  c3 = (color & 0x001f) << 1;
+    if (x1 < x2) {
+        if (y1 < y2) {
+            //  normal
+            unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3};
+            if (reversal) {
+                unsigned char cmdN[] = {0xa0, 0x70};
+                cmdOut(cmdN, 2);
+                reversal = false;
+            }
+            cmdOut(cmd, 8);
+        }
+        else if (y1 > y2) {
+            //  reversal
+            if (! reversal) {
+                unsigned char cmdR[] = {0xa0, 0x72};
+                cmdOut(cmdR, 2);
+                reversal = true;
+            }
+            unsigned char cmd[]  = {0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3};
+            cmdOut(cmd, 8);
+        }
+        else {  //  y1 == y2
+            //  normal
+            unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3};
+            if (reversal) {
+                unsigned char cmdN[] = {0xa0, 0x70};
+                cmdOut(cmdN, 2);
+                reversal = false;
+            }
+            cmdOut(cmd, 8);
+        }
+    }
+    else if (x1 > x2) {
+        if (y1 < y2) {
+            //  reversal
+            if (! reversal) {
+                unsigned char cmdR[] = {0xa0, 0x72};
+                cmdOut(cmdR, 2);
+                reversal = true;
+            }
+            unsigned char cmd[]  = {0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3};
+            cmdOut(cmd, 8);
+        }
+        else if (y1 > y2) {
+            //  normal
+            unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3};
+            if (reversal) {
+                unsigned char cmdN[] = {0xa0, 0x70};
+                cmdOut(cmdN, 2);
+                reversal = false;
+            }
+            cmdOut(cmd, 8);
+        }
+        else {  //  y1 == y2
+            //  reversal
+            unsigned char cmd[] = {0xa0, 0x72, 
+                                   0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3,
+                                   0xa0, 0x70 };
+            cmdOut(cmd, 12);
+        }
+    }
+    else {  //  x1 == x2
+        if (y1 < y2) {
+            //  normal
+            unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3};
+            if (reversal) {
+                unsigned char cmdN[] = {0xa0, 0x70};
+                cmdOut(cmdN, 2);
+                reversal = false;
+            }
+            cmdOut(cmd, 8);
+        }
+        else if (y1 > y2) {
+            //  normal (force downward)
+            unsigned char cmd[]  = {0x21, x2, y2, x1, y1, c1, c2, c3};
+            cmdOut(cmd, 8);
+        }
+        else {  //  y1 == y2
+            //  normal (point)
+            unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3};
+            if (reversal) {
+                unsigned char cmdN[] = {0xa0, 0x70};
+                cmdOut(cmdN, 2);
+                reversal = false;
+            }
+            cmdOut(cmd, 8);
+        }
+    }
+    //  wait
+    wait_us(1);
+}
+
+void OLED::circle(int x, int y, int r, unsigned short color, int fill)
+{
+    //  exception
+    if (r < 1) {
+        line(x, y, x, y, color);
+        return;
+    } else if (r == 1) {
+        rect(x - 1, y - 1, 3, 3, color, fill);
+        return;
+    }
+    //  ok, go
+    int xx = 0, 
+        yy = r, 
+        err = 2 - 2 * r;
+    //  iteration
+    do {
+        //  draw it! 
+        if (fill) {
+            line(x + xx, y + yy, x + xx, y, color);
+            line(x - xx, y + yy, x, y + yy, color);
+            line(x - xx, y - yy, x - xx, y, color);
+            line(x + xx, y - yy, x, y - yy, color);
+        }
+        else {
+            point(x + xx, y + yy, color);
+            point(x - xx, y + yy, color);
+            point(x - xx, y - yy, color);
+            point(x + xx, y - yy, color);
+        }
+        //  walk
+        if (err > -yy) {
+            yy--;
+            err += 1 - 2 * yy;
+        }
+        if (err <= xx) {
+            xx++;
+            err += 1 + 2 * xx;
+        }
+    } while (yy >= 0);
+}
+
+void OLED::ellipse(int x, int y, int rx, int ry, unsigned short color, int fill)
+{
+    //  exception
+    if (rx < 1) {
+        line(x, y - ry, x, y + ry, color);
+        return;
+    }
+    else if (ry < 1) {
+        line(x - rx, y, x + rx, y, color);
+        return;
+    }
+    //  ok, go
+    int xx = -rx, yy = 0;
+    int e2 = ry, 
+        dx = (2 * xx + 1) * e2 * e2, 
+        dy = xx * xx, 
+        err = dx + dy;
+    do {
+        if (fill) {
+            line(x + xx, y + yy, x + xx, y, color);
+            line(x - xx, y + yy, x, y + yy, color);
+            line(x - xx, y - yy, x - xx, y, color);
+            line(x + xx, y - yy, x, y - yy, color);
+        }
+        else {
+            point(x + xx, y + yy, color);
+            point(x - xx, y + yy, color);
+            point(x - xx, y - yy, color);
+            point(x + xx, y - yy, color);
+        }
+        e2 = 2 * err;
+        if (e2 >= dx) {
+            xx++;
+            dx += 2 * ry * ry;
+            err += dx;
+        }
+        if (e2 <= dy) {
+            yy++;
+            dy += 2 * rx * rx;
+            err += dy;
+        }
+    } while (xx <= 0);
+    if (fill) {
+        while (yy++ < ry) {
+            line(x, y + yy, x, y, color);
+            line(x, y - yy, x, y, color);
+        }
+    }
+    else {
+        while (yy++ < ry) {
+            point(x, y + yy, color);
+            point(x, y - yy, color);
+        }
+    }
+}
+
+void OLED::image(int x, int y, int w, int h, unsigned short *image16)
+{
+    //  un-reverse
+    if (reversal) {
+        unsigned char cmdN[] = {0xa0, 0x70};
+        cmdOut(cmdN, 2);
+        reversal = false;
+    }
+    //  setup the region to fill
+    unsigned char cmd[]={0x15, x, x+w-1, 0x75, y, y+h-1};
+    cmdOut(cmd, 6);
+    //  fill up the region with the image data
+    dataOut(image16, w * h);
+    //  wait
+    wait_us(100);
+}
+
+void OLED::image(int x, int y, int w, int h, const unsigned short *image16)
+{
+    image(x, y, w, h, (unsigned short *) image16);
+}
+
+void OLED::image(int x, int y, int w, int h, unsigned char *image8x3)
+{
+    //  un-reverse
+    if (reversal) {
+        unsigned char cmdN[] = {0xa0, 0x70};
+        cmdOut(cmdN, 2);
+        reversal = false;
+    }
+    //  setup the region to fill
+    unsigned char cmd[]={0x15, x, x+w-1, 0x75, y, y+h-1};
+    cmdOut(cmd, 6);
+    //  fill up the region with the image data
+    int size = w * h;
+    for (int k = 0; k < size; k++) {
+        unsigned char r, g, b;
+        b = *image8x3++;
+        g = *image8x3++;
+        r = *image8x3++;
+        unsigned short data16 = color(r, g, b);
+        dataOut(&data16, 1);
+    }
+    //  wait
+    wait_us(100);
+}
+
+void OLED::image(int x, int y, int w, int h, const unsigned char *image8x3)
+{
+    image(x, y, w, h, (unsigned char *) image8x3);
+}
+
+void OLED::text(int x, int y, char *string, unsigned short color)
+{
+    int len = strlen(string);
+    for (int i = 0; i < len; i++) {
+        int xx = x + i * 6;
+        unsigned char code = string[i];
+        if (code < 0x20 || code >= 0x80) continue;
+        unsigned char *font = font6x8 + ((code - 0x20) * 6);
+        for (int fx = 0; fx < 6; fx++) {
+            if (xx + fx > 95) break;
+            unsigned char line = *(font + fx);
+            for (int fy = 0, bit = 0x01; fy < 8; fy++, bit <<= 1) {
+                if (line & bit) point(xx + fx, y + fy, color);
+            }
+        }
+    }
+}
+
+void OLED::text(int x, int y, char *string, unsigned short colorF, unsigned short colorB)
+{
+    //  clear the background
+    int w = strlen(string) * 6;
+    if (x + w > 95) w = 95 - x;
+    rect(x, y, w, 8, colorB, 1);
+    //  overwrite the text
+    text(x, y, string, colorF);
+}
\ No newline at end of file
diff -r 000000000000 -r 76a5ae915f62 OLEDaccel.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OLEDaccel.h	Fri Aug 17 15:30:29 2012 +0000
@@ -0,0 +1,33 @@
+//
+//  OLEDaccel: 96x64 OLED driver
+//  (version 0.2, August 15, 2012)
+//  xkozima@myu.ac.jp
+
+#pragma once
+#include "mbed.h"
+
+class OLED {
+public:
+    OLED(PinName rstPin, PinName csPin, PinName dcPin, PinName mosiPin, PinName sckPin);
+    void clear(unsigned short color);
+    void point(int x, int y, unsigned short color);
+    void line(int x1, int y1, int x2, int y2, unsigned short color);
+    void rect(int x, int y, int w, int h, unsigned short color, int fill);
+    void circle(int x, int y, int r, unsigned short color, int fill);
+    void ellipse(int x, int y, int rx, int ry, unsigned short color, int fill);
+    void image(int x, int y, int w, int h, unsigned short *image16);
+    void image(int x, int y, int w, int h, const unsigned short *image16);
+    void image(int x, int y, int w, int h, unsigned char *image8x3);
+    void image(int x, int y, int w, int h, const unsigned char *image8x3);
+    void text(int x, int y, char *string, unsigned short color);
+    void text(int x, int y, char *string, unsigned short colorF, unsigned short colorB);
+    unsigned short color(int r, int g, int b);
+private:
+    void cmdOutOne(unsigned char cmdOne);
+    void cmdOut(unsigned char *cmd, int length);
+    void dataOut(unsigned short *data, int length);
+    DigitalOut rst, cs, dc;
+    SPI spi;
+    bool reversal;
+    bool filling;
+};
\ No newline at end of file
diff -r 000000000000 -r 76a5ae915f62 font6x8.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/font6x8.h	Fri Aug 17 15:30:29 2012 +0000
@@ -0,0 +1,194 @@
+unsigned char font6x8[] = {
+    //  0x20 (SPC)
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    //  0x21 (!)
+    0x00, 0x00, 0x5f, 0x00, 0x00, 0x00,
+    //  0x22 (")
+    0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+    //  0x23 (#)
+    0x14, 0x7f, 0x14, 0x7f, 0x14, 0x00,
+    //  0x24 ($)
+    0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x00,
+    //  0x25 (%)
+    0x46, 0x26, 0x18, 0x64, 0x62, 0x00,
+    //  0x26 (&)
+    0x30, 0x4b, 0x4d, 0x33, 0x48, 0x00,
+    //  0x27 (')
+    0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+    //  0x28 (()
+    0x00, 0x1c, 0x22, 0x41, 0x00, 0x00,
+    //  0x29 ())
+    0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,
+    //  0x2a (*)
+    0x2a, 0x1c, 0x7f, 0x1c, 0x2a, 0x00,
+    //  0x2b (+)
+    0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,
+    //  0x2c (,)
+    0x00, 0x00, 0x40, 0x20, 0x00, 0x00,
+    //  0x2d (-)
+    0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
+    //  0x2e (.)
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    //  0x2f (/)
+    0x40, 0x30, 0x08, 0x06, 0x01, 0x00,
+    //  0x30 (0)
+    0x3e, 0x61, 0x5d, 0x43, 0x3e, 0x00,
+    //  0x31 (1)
+    0x00, 0x00, 0x01, 0x7f, 0x00, 0x00,
+    //  0x32 (2)
+    0x62, 0x51, 0x51, 0x49, 0x46, 0x00,
+    //  0x33 (3)
+    0x22, 0x41, 0x49, 0x49, 0x36, 0x00,
+    //  0x34 (4)
+    0x30, 0x2e, 0x21, 0x7f, 0x20, 0x00,
+    //  0x35 (5)
+    0x4f, 0x49, 0x49, 0x49, 0x31, 0x00,
+    //  0x36 (6)
+    0x3e, 0x49, 0x49, 0x49, 0x32, 0x00,
+    //  0x37 (7)
+    0x01, 0x61, 0x19, 0x05, 0x03, 0x00,
+    //  0x38 (8)
+    0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
+    //  0x39 (9)
+    0x26, 0x49, 0x49, 0x49, 0x3e, 0x00,
+    //  0x3a (:)
+    0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
+    //  0x3b (;)
+    0x00, 0x00, 0x40, 0x24, 0x00, 0x00,
+    //  0x3c (<)
+    0x00, 0x08, 0x14, 0x22, 0x00, 0x00,
+    //  0x3d (=)
+    0x00, 0x14, 0x14, 0x14, 0x14, 0x00,
+    //  0x3e (>)
+    0x00, 0x22, 0x14, 0x08, 0x00, 0x00,
+    //  0x3f (?)
+    0x06, 0x01, 0x59, 0x09, 0x06, 0x00,
+    //  0x40 (@)
+    0x3e, 0x41, 0x5d, 0x55, 0x5e, 0x00,
+    //  0x41 (A)
+    0x7e, 0x11, 0x11, 0x11, 0x7e, 0x00,
+    //  0x42 (B)
+    0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,
+    //  0x43 (C)
+    0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,
+    //  0x44 (D)
+    0x7f, 0x41, 0x41, 0x22, 0x1c, 0x00,
+    //  0x45 (E)
+    0x7f, 0x49, 0x49, 0x49, 0x41, 0x00,
+    //  0x46 (F)
+    0x7f, 0x09, 0x09, 0x09, 0x01, 0x00,
+    //  0x47 (G)
+    0x3e, 0x41, 0x51, 0x51, 0x72, 0x00,
+    //  0x48 (H)
+    0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,
+    //  0x49 (I)
+    0x00, 0x41, 0x7f, 0x41, 0x00, 0x00,
+    //  0x4a (J)
+    0x30, 0x40, 0x41, 0x41, 0x3f, 0x00,
+    //  0x4b (K)
+    0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,
+    //  0x4c (L)
+    0x7f, 0x40, 0x40, 0x40, 0x40, 0x00,
+    //  0x4d (M)
+    0x7f, 0x06, 0x18, 0x06, 0x7f, 0x00,
+    //  0x4e (N)
+    0x7f, 0x02, 0x1c, 0x20, 0x7f, 0x00,
+    //  0x4f (O)
+    0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,
+    //  0x50 (P)
+    0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,
+    //  0x51 (Q)
+    0x3e, 0x41, 0x51, 0x61, 0x7e, 0x00,
+    //  0x52 (R)
+    0x7f, 0x09, 0x09, 0x19, 0x66, 0x00,
+    //  0x53 (S)
+    0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
+    //  0x54 (T)
+    0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,
+    //  0x55 (U)
+    0x3f, 0x40, 0x40, 0x40, 0x3f, 0x00,
+    //  0x56 (V)
+    0x07, 0x18, 0x60, 0x18, 0x07, 0x00,
+    //  0x57 (W)
+    0x7f, 0x30, 0x0c, 0x30, 0x7f, 0x00,
+    //  0x58 (X)
+    0x41, 0x36, 0x08, 0x36, 0x41, 0x00,
+    //  0x59 (Y)
+    0x03, 0x0c, 0x70, 0x0c, 0x03, 0x00,
+    //  0x5a (Z)
+    0x61, 0x51, 0x49, 0x45, 0x43, 0x00,
+    //  0x5b ([)
+    0x00, 0x00, 0x7f, 0x41, 0x00, 0x00,
+    //  0x5c (\)
+    0x01, 0x06, 0x08, 0x30, 0x40, 0x00,
+    //  0x5d (])
+    0x00, 0x00, 0x41, 0x7f, 0x00, 0x00,
+    //  0x5e (^)
+    0x00, 0x02, 0x01, 0x02, 0x00, 0x00,
+    //  0x5f (_)
+    0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
+    //  0x60 (`)
+    0x00, 0x01, 0x02, 0x04, 0x00, 0x00,
+    //  0x61 (a)
+    0x24, 0x54, 0x54, 0x54, 0x38, 0x40,
+    //  0x62 (b)
+    0x7f, 0x44, 0x44, 0x44, 0x38, 0x00,
+    //  0x63 (c)
+    0x38, 0x44, 0x44, 0x44, 0x44, 0x00,
+    //  0x64 (d)
+    0x38, 0x44, 0x44, 0x44, 0x7f, 0x00,
+    //  0x65 (e)
+    0x38, 0x54, 0x54, 0x54, 0x5c, 0x00,
+    //  0x66 (f)
+    0x00, 0x08, 0x7f, 0x09, 0x00, 0x00,
+    //  0x67 (g)
+    0x58, 0x54, 0x54, 0x54, 0x3c, 0x00,
+    //  0x68 (h)
+    0x7f, 0x04, 0x04, 0x04, 0x78, 0x00,
+    //  0x69 (i)
+    0x00, 0x00, 0x7a, 0x00, 0x00, 0x00,
+    //  0x6a (j)
+    0x20, 0x40, 0x40, 0x40, 0x3a, 0x00,
+    //  0x6b (k)
+    0x7f, 0x10, 0x10, 0x28, 0x48, 0x00,
+    //  0x6c (l)
+    0x00, 0x00, 0x41, 0x7f, 0x40, 0x00,
+    //  0x6d (m)
+    0x7c, 0x04, 0x78, 0x04, 0x78, 0x00,
+    //  0x6e (n)
+    0x7c, 0x04, 0x04, 0x04, 0x78, 0x00,
+    //  0x6f (o)
+    0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
+    //  0x70 (p)
+    0x7c, 0x24, 0x24, 0x24, 0x18, 0x00,
+    //  0x71 (q)
+    0x18, 0x24, 0x24, 0x24, 0x7c, 0x00,
+    //  0x72 (r)
+    0x7c, 0x08, 0x04, 0x04, 0x04, 0x00,
+    //  0x73 (s)
+    0x58, 0x54, 0x54, 0x54, 0x34, 0x00,
+    //  0x74 (t)
+    0x00, 0x04, 0x7e, 0x44, 0x00, 0x00,
+    //  0x75 (u)
+    0x3c, 0x40, 0x40, 0x40, 0x7c, 0x00,
+    //  0x76 (v)
+    0x0c, 0x30, 0x40, 0x30, 0x0c, 0x00,
+    //  0x77 (w)
+    0x7c, 0x20, 0x18, 0x20, 0x7c, 0x00,
+    //  0x78 (x)
+    0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
+    //  0x79 (y)
+    0x44, 0x28, 0x10, 0x08, 0x04, 0x00,
+    //  0x7a (z)
+    0x44, 0x64, 0x54, 0x4c, 0x44, 0x00,
+    //  0x7b ({)
+    0x00, 0x08, 0x3e, 0x41, 0x00, 0x00,
+    //  0x7c (|)
+    0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
+    //  0x7d (})
+    0x00, 0x00, 0x41, 0x3e, 0x08, 0x00,
+    //  0x7e (~)
+    0x02, 0x01, 0x02, 0x01, 0x01, 0x00,
+    //  0x7f (DEL)
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};