SG12864A

Dependents:   SG12864A_TestProgram

Files at this revision

API Documentation at this revision

Comitter:
shintamainjp
Date:
Tue Aug 10 12:52:53 2010 +0000
Parent:
4:200d1ea4e76e
Child:
6:bc2da4c1c5a0
Commit message:

Changed in this revision

SG12864A.cpp Show annotated file Show diff for this revision Revisions of this file
SG12864A.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/SG12864A.cpp	Tue Aug 10 12:36:05 2010 +0000
+++ b/SG12864A.cpp	Tue Aug 10 12:52:53 2010 +0000
@@ -1,528 +1,523 @@
-/**
- * SG12864A Graphics LCD module driver class (Version 0.0.1)
- *
- * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
- * http://shinta.main.jp/
- *
- * See also ...
- * http://mbed.org/users/shintamainjp/notebook/sg12864asunlike-display-graphics-lcd-driver/
- */
-
-#include "SG12864A.h"
-
-#define setPixel(x,y) buffer[((COLUMNS * 2)* ((y) / 8)) + (x)] |= (1 << ((y) % 8))
-#define unsetPixel(x,y) buffer[((COLUMNS * 2)* ((y) / 8)) + (x)] &= ~(1 << ((y) % 8))
-#define swap(a,b) {int c=a;a=b;b=c;}
-
-const uint8_t SG12864A::font5x7_data[] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, // (white space)
-    0x00, 0x00, 0x5F, 0x00, 0x00, // !
-    0x00, 0x07, 0x00, 0x07, 0x00, // "
-    0x14, 0x7F, 0x14, 0x7F, 0x14, // #
-    0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
-    0x23, 0x13, 0x08, 0x64, 0x62, // %
-    0x36, 0x49, 0x55, 0x22, 0x50, // &
-    0x00, 0x05, 0x03, 0x00, 0x00, // '
-    0x00, 0x1C, 0x22, 0x41, 0x00, // (
-    0x00, 0x41, 0x22, 0x1C, 0x00, // )
-    0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
-    0x08, 0x08, 0x3E, 0x08, 0x08, // +
-    0x00, 0x50, 0x30, 0x00, 0x00, // ,
-    0x08, 0x08, 0x08, 0x08, 0x08, // -
-    0x00, 0x60, 0x60, 0x00, 0x00, // .
-    0x20, 0x10, 0x08, 0x04, 0x02, // /
-    0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
-    0x00, 0x42, 0x7F, 0x40, 0x00, // 1
-    0x42, 0x61, 0x51, 0x49, 0x46, // 2
-    0x21, 0x41, 0x45, 0x4B, 0x31, // 3
-    0x18, 0x14, 0x12, 0x7F, 0x10, // 4
-    0x27, 0x45, 0x45, 0x45, 0x39, // 5
-    0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
-    0x01, 0x71, 0x09, 0x05, 0x03, // 7
-    0x36, 0x49, 0x49, 0x49, 0x36, // 8
-    0x06, 0x49, 0x49, 0x29, 0x1E, // 9
-    0x00, 0x36, 0x36, 0x00, 0x00, // :
-    0x00, 0x56, 0x36, 0x00, 0x00, // ;
-    0x00, 0x08, 0x14, 0x22, 0x41, // <
-    0x14, 0x14, 0x14, 0x14, 0x14, // =
-    0x41, 0x22, 0x14, 0x08, 0x00, // >
-    0x02, 0x01, 0x51, 0x09, 0x06, // ?
-    0x32, 0x49, 0x79, 0x41, 0x3E, // @
-    0x7E, 0x11, 0x11, 0x11, 0x7E, // A
-    0x7F, 0x49, 0x49, 0x49, 0x36, // B
-    0x3E, 0x41, 0x41, 0x41, 0x22, // C
-    0x7F, 0x41, 0x41, 0x22, 0x1C, // D
-    0x7F, 0x49, 0x49, 0x49, 0x41, // E
-    0x7F, 0x09, 0x09, 0x01, 0x01, // F
-    0x3E, 0x41, 0x41, 0x51, 0x32, // G
-    0x7F, 0x08, 0x08, 0x08, 0x7F, // H
-    0x00, 0x41, 0x7F, 0x41, 0x00, // I
-    0x20, 0x40, 0x41, 0x3F, 0x01, // J
-    0x7F, 0x08, 0x14, 0x22, 0x41, // K
-    0x7F, 0x40, 0x40, 0x40, 0x40, // L
-    0x7F, 0x02, 0x04, 0x02, 0x7F, // M
-    0x7F, 0x04, 0x08, 0x10, 0x7F, // N
-    0x3E, 0x41, 0x41, 0x41, 0x3E, // O
-    0x7F, 0x09, 0x09, 0x09, 0x06, // P
-    0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
-    0x7F, 0x09, 0x19, 0x29, 0x46, // R
-    0x46, 0x49, 0x49, 0x49, 0x31, // S
-    0x01, 0x01, 0x7F, 0x01, 0x01, // T
-    0x3F, 0x40, 0x40, 0x40, 0x3F, // U
-    0x1F, 0x20, 0x40, 0x20, 0x1F, // V
-    0x7F, 0x20, 0x18, 0x20, 0x7F, // W
-    0x63, 0x14, 0x08, 0x14, 0x63, // X
-    0x03, 0x04, 0x78, 0x04, 0x03, // Y
-    0x61, 0x51, 0x49, 0x45, 0x43, // Z
-    0x00, 0x00, 0x7F, 0x41, 0x41, // [
-    0x02, 0x04, 0x08, 0x10, 0x20, // /
-    0x41, 0x41, 0x7F, 0x00, 0x00, // ]
-    0x04, 0x02, 0x01, 0x02, 0x04, // ^
-    0x40, 0x40, 0x40, 0x40, 0x40, // _
-    0x00, 0x01, 0x02, 0x04, 0x00, // `
-    0x20, 0x54, 0x54, 0x54, 0x78, // a
-    0x7F, 0x48, 0x44, 0x44, 0x38, // b
-    0x38, 0x44, 0x44, 0x44, 0x20, // c
-    0x38, 0x44, 0x44, 0x48, 0x7F, // d
-    0x38, 0x54, 0x54, 0x54, 0x18, // e
-    0x08, 0x7E, 0x09, 0x01, 0x02, // f
-    0x08, 0x14, 0x54, 0x54, 0x3C, // g
-    0x7F, 0x08, 0x04, 0x04, 0x78, // h
-    0x00, 0x44, 0x7D, 0x40, 0x00, // i
-    0x20, 0x40, 0x44, 0x3D, 0x00, // j
-    0x00, 0x7F, 0x10, 0x28, 0x44, // k
-    0x00, 0x41, 0x7F, 0x40, 0x00, // l
-    0x7C, 0x04, 0x18, 0x04, 0x78, // m
-    0x7C, 0x08, 0x04, 0x04, 0x78, // n
-    0x38, 0x44, 0x44, 0x44, 0x38, // o
-    0x7C, 0x14, 0x14, 0x14, 0x08, // p
-    0x08, 0x14, 0x14, 0x18, 0x7C, // q
-    0x7C, 0x08, 0x04, 0x04, 0x08, // r
-    0x48, 0x54, 0x54, 0x54, 0x20, // s
-    0x04, 0x3F, 0x44, 0x40, 0x20, // t
-    0x3C, 0x40, 0x40, 0x20, 0x7C, // u
-    0x1C, 0x20, 0x40, 0x20, 0x1C, // v
-    0x3C, 0x40, 0x30, 0x40, 0x3C, // w
-    0x44, 0x28, 0x10, 0x28, 0x44, // x
-    0x0C, 0x50, 0x50, 0x50, 0x3C, // y
-    0x44, 0x64, 0x54, 0x4C, 0x44, // z
-    0x00, 0x08, 0x36, 0x41, 0x00, // {
-    0x00, 0x00, 0x7F, 0x00, 0x00, // |
-    0x00, 0x41, 0x36, 0x08, 0x00, // }
-    0x08, 0x08, 0x2A, 0x1C, 0x08, // ->
-    0x08, 0x1C, 0x2A, 0x08, 0x08  // <-
-};
-
-SG12864A::SG12864A(PinName di,
-                   PinName rw,
-                   PinName en,
-                   PinName db0,
-                   PinName db1,
-                   PinName db2,
-                   PinName db3,
-                   PinName db4,
-                   PinName db5,
-                   PinName db6,
-                   PinName db7,
-                   PinName cs1,
-                   PinName cs2,
-                   PinName res)
-        :
-        ioDI(di),
-        ioRW(rw),
-        ioEN(en),
-        ioDB(db0, db1, db2, db3, db4, db5, db6, db7),
-        ioCS1(cs1),
-        ioCS2(cs2),
-        ioRES(res) {
-    bufferClear();
-    setDirectionToWrite();
-}
-
-SG12864A::~SG12864A() {
-}
-
-void SG12864A::bufferPush(void) {
-    for (uint8_t i = 0; i < PAGES; i++) {
-        // CS1
-        setPageAddress(SG12864A::CS1, i);
-        setColumnAddress(SG12864A::CS1, 0);
-        for (uint8_t j = 0; j < COLUMNS; j++) {
-            writeData(CS1, buffer[0 + ((COLUMNS * 2) * i) + j]);
-        }
-        // CS2
-        setPageAddress(SG12864A::CS2, i);
-        setColumnAddress(SG12864A::CS2, 0);
-        for (uint8_t j = 0; j < COLUMNS; j++) {
-            writeData(CS2, buffer[COLUMNS + ((COLUMNS * 2) * i) + j]);
-        }
-    }
-}
-
-void SG12864A::bufferPull(void) {
-}
-
-void SG12864A::bufferClear(bool reverse) {
-    for (int i = 0; i < sizeof(buffer); i++) {
-        if (reverse) {
-            buffer[i] = 0xFF;
-        } else {
-            buffer[i] = 0x00;
-        }
-    }
-}
-
-void SG12864A::bufferDrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) {
-    /*
-     * Bresenham's line algorithm
-     */
-    bool steep = abs(y2 - y1) > abs(x2 - x1);
-    if (steep) {
-        swap(x1, y1);
-        swap(x2, y2);
-    }
-    if (x1 > x2) {
-        swap(x1, x2);
-        swap(y1, y2);
-    }
-    int deltax = x2 - x1;
-    int deltay = abs(y2 - y1);
-    int error = deltax / 2;
-    int ystep;
-    int y = y1;
-    if (y1 < y2) {
-        ystep = 1;
-    } else {
-        ystep = -1;
-    }
-    for (int x = x1; x <= x2; x++) {
-        if (steep) {
-            if (reverse) {
-                unsetPixel(y, x);
-            } else {
-                setPixel(y, x);
-            }
-        } else {
-            if (reverse) {
-                unsetPixel(x, y);
-            } else {
-                setPixel(x, y);
-            }
-        }
-        error = error - deltay;
-        if (error < 0) {
-            y = y + ystep;
-            error = error + deltax;
-        }
-    }
-}
-
-void SG12864A::bufferDrawBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) {
-    for (int x = x1; x <= x2; x++) {
-        if (reverse) {
-            unsetPixel(x, y1);
-            unsetPixel(x, y2);
-        } else {
-            setPixel(x, y1);
-            setPixel(x, y2);
-        }
-    }
-    for (int y = y1; y <= y2; y++) {
-        if (reverse) {
-            unsetPixel(x1, y);
-            unsetPixel(x2, y);
-        } else {
-            setPixel(x1, y);
-            setPixel(x2, y);
-        }
-    }
-}
-
-void SG12864A::bufferFillBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) {
-    for (int x = x1; x <= x2; x++) {
-        for (int y = y1; y <= y2; y++) {
-            if (reverse) {
-                unsetPixel(x, y);
-            } else {
-                setPixel(x, y);
-            }
-        }
-    }
-}
-
-void SG12864A::bufferDrawString(uint8_t x, uint8_t y, char * str, bool reverse) {
-    char *p = str;
-    int cnt = 0;
-    while (*p) {
-        bufferDrawChar(x + (FONT_X * cnt), y, *p, reverse);
-        p++;
-        cnt++;
-    }
-}
-
-void SG12864A::bufferDrawChar(uint8_t x, uint8_t y, char c, bool reverse) {
-    if ((FONT_MIN_CODE <= c) &&(c <= FONT_MAX_CODE)) {
-        int aofs = (c - FONT_MIN_CODE) * FONT_X;
-        for (int i = 0; i < FONT_X; i++) {
-            uint8_t pat = font5x7_data[aofs + i];
-            for (int j = 0; j < FONT_Y; j++) {
-                if (pat & (1 << j)) {
-                    if (reverse) {
-                        unsetPixel(x + i, y + j);
-                    } else {
-                        setPixel(x + i, y + j);
-                    }
-                } else {
-                    if (reverse) {
-                        setPixel(x + i, y + j);
-                    } else {
-                        unsetPixel(x + i, y + j);
-                    }
-                }
-            }
-        }
-    } else {
-        for (int i = 0; i < FONT_X; i++) {
-            uint8_t pat = (i % 2) ? 0x55 : 0xAA;
-            for (int j = 0; j < FONT_Y; j++) {
-                if (pat & (1 << j)) {
-                    if (reverse) {
-                        unsetPixel(x + i, y + j);
-                    } else {
-                        setPixel(x + i, y + j);
-                    }
-                } else {
-                    if (reverse) {
-                        setPixel(x + i, y + j);
-                    } else {
-                        unsetPixel(x + i, y + j);
-                    }
-                }
-            }
-        }
-    }
-}
-
-void SG12864A::bufferDrawCheckbox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state, bool reverse) {
-    bufferDrawBox(x1, y1, x2, y2, reverse);
-    if (state) {
-        bufferDrawLine(x1, y1, x2, y2, reverse);
-        bufferDrawLine(x1, y2, x2, y1, reverse);
-    }
-}
-
-void SG12864A::bufferDrawProgressbar(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, int min, int max, int value, bool horizontal, bool reverse) {
-    bufferDrawBox(x1, y1, x2, y2, reverse);
-    if ((value < min) || (max < value)) {
-        return;
-    }
-    int tmp_max = max - min;
-    int tmp_val = value - min;
-    if (horizontal) {
-        int pix = ((y2 - y1) * tmp_val) / tmp_max;
-        bufferFillBox(x1 + 1, y1 + 1, x1 - 1, y2 + pix - 1, reverse);
-    } else {
-        int pix = ((x2 - x1) * tmp_val) / tmp_max;
-        bufferFillBox(x1 + 1, y1 + 1, x1 + pix - 1, y2 - 1, reverse);
-    }
-}
-
-/**
- * High Level Interface.
- *
- * Reset display module.
- */
-void SG12864A::reset(void) {
-    reset(true);
-    wait_ms(200);
-    reset(false);
-    wait_ms(200);
-
-    setDisplayOnOff(SG12864A::CS1, true);
-    setDisplayOnOff(SG12864A::CS2, true);
-    setDisplayStartLine(SG12864A::CS1, 0);
-    setDisplayStartLine(SG12864A::CS2, 0);
-    setPageAddress(SG12864A::CS1, 0);
-    setPageAddress(SG12864A::CS2, 0);
-    setColumnAddress(SG12864A::CS1, 0);
-    setColumnAddress(SG12864A::CS2, 0);
-}
-
-/**
- * High Level Interface.
- *
- * Clear display module.
- */
-void SG12864A::clear(void) {
-    for (uint8_t page = 0; page < PAGES; page++) {
-        for (uint8_t column = 0; column < COLUMNS; column++) {
-            // CS1
-            setPageAddress(SG12864A::CS1, page);
-            setColumnAddress(SG12864A::CS1, column);
-            writeData(CS1, 0x00);
-            // CS2
-            setPageAddress(SG12864A::CS2, page);
-            setColumnAddress(SG12864A::CS2, column);
-            writeData(CS2, 0x00);
-        }
-    }
-    // CS1
-    setPageAddress(SG12864A::CS1, 0);
-    setColumnAddress(SG12864A::CS1, 0);
-    writeData(CS1, 0x00);
-    // CS2
-    setPageAddress(SG12864A::CS2, 0);
-    setColumnAddress(SG12864A::CS2, 0);
-    writeData(CS2, 0x00);
-}
-
-/**
- * Middle Level Interface.
- *
- * Set display on/off.
- *
- * @param t Target (CS1, CS2).
- * @param on ON/OFF (true, false).
- */
-void SG12864A::setDisplayOnOff(Target t, bool on) {
-    setDirectionToWrite();
-    uint8_t c = 0x3e | (on ? 0x01 : 0x00);
-    write(t, SG12864A::Instruction, c);
-    wait_us(1);
-}
-
-/**
- * Middle Level Interface.
- *
- * Set display start line.
- *
- * @param t Target (CS1, CS2).
- * @param addr Display start line (0-63).
- */
-void SG12864A::setDisplayStartLine(Target t, uint8_t addr) {
-    setDirectionToWrite();
-    uint8_t c = 0xc0 | (addr & 0x3f);
-    write(t, SG12864A::Instruction, c);
-    wait_us(1);
-}
-
-/**
- * Middle Level Interface.
- *
- * Set page address.
- *
- * @param t Target (CS1, CS2).
- * @param addr Page address(0-7).
- */
-void SG12864A::setPageAddress(Target t, uint8_t addr) {
-    setDirectionToWrite();
-    uint8_t c = 0xb8 | (addr & 0x07);
-    write(t, SG12864A::Instruction, c);
-    wait_us(1);
-}
-
-/**
- * Middle Level Interface.
- *
- * Set column address.
- *
- * @param t Target. (CS1, CS2)
- * @param addr Column address (0-63).
- */
-void SG12864A::setColumnAddress(Target t, uint8_t addr) {
-    setDirectionToWrite();
-    uint8_t c = 0x40 | (addr & 0x3f);
-    write(t, SG12864A::Instruction, c);
-    wait_us(1);
-}
-
-/**
- * Middle Level Interface.
- */
-void SG12864A::readStatus(Target t, uint8_t *c) {
-    setDirectionToRead();
-    read(t, SG12864A::Instruction, c);
-    wait_us(1);
-}
-
-/**
- * Middle Level Interface.
- */
-void SG12864A::writeData(Target t, uint8_t c) {
-    setDirectionToWrite();
-    write(t, SG12864A::Data, c);
-    wait_us(1);
-}
-
-/**
- * Middle Level Interface.
- */
-void SG12864A::readData(Target t, uint8_t *c) {
-    setDirectionToRead();
-    read(t, SG12864A::Data, c);
-    wait_us(1);
-}
-
-/**
- * Low Level Interface.
- */
-void SG12864A::setDirectionToRead() {
-    ioDB.input();
-    ioRW = 1;
-}
-
-/**
- * Low Level Interface.
- */
-void SG12864A::setDirectionToWrite() {
-    ioDB.output();
-    ioRW = 0;
-}
-
-/**
- * Low Level Interface.
- */
-void SG12864A::write(Target t, Mode m, uint8_t c) {
-    switch (t) {
-        case CS1:
-            ioCS1 = 1;
-            ioCS2 = 0;
-            break;
-        case CS2:
-            ioCS1 = 0;
-            ioCS2 = 1;
-            break;
-    }
-    switch (m) {
-        case Data:
-            ioDI = 1;
-            break;
-        case Instruction:
-            ioDI = 0;
-            break;
-    }
-    ioDB = c;
-    wait_us(1);
-    ioEN = 1;
-    wait_us(1);
-    ioEN = 0;
-    wait_us(5);
-}
-
-/**
- * Low Level Interface.
- */
-void SG12864A::read(Target t, Mode m, uint8_t *c) {
-    // TODO
-}
-
-/**
- * Low Level Interface.
- */
-void SG12864A::reset(bool b) {
-    if (b) {
-        ioRES = 0;
-    } else {
-        ioRES = 1;
-    }
-}
+/**
+ * SG12864A Graphics LCD module driver class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ *
+ * See also ...
+ * http://mbed.org/users/shintamainjp/notebook/sg12864asunlike-display-graphics-lcd-driver/
+ */
+
+#include "SG12864A.h"
+
+#define setPixel(x,y) buffer[((COLUMNS * 2)* ((y) / 8)) + (x)] |= (1 << ((y) % 8))
+#define unsetPixel(x,y) buffer[((COLUMNS * 2)* ((y) / 8)) + (x)] &= ~(1 << ((y) % 8))
+#define swap(a,b) {int c=a;a=b;b=c;}
+
+const uint8_t SG12864A::font5x7_data[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, // (white space)
+    0x00, 0x00, 0x5F, 0x00, 0x00, // !
+    0x00, 0x07, 0x00, 0x07, 0x00, // "
+    0x14, 0x7F, 0x14, 0x7F, 0x14, // #
+    0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
+    0x23, 0x13, 0x08, 0x64, 0x62, // %
+    0x36, 0x49, 0x55, 0x22, 0x50, // &
+    0x00, 0x05, 0x03, 0x00, 0x00, // '
+    0x00, 0x1C, 0x22, 0x41, 0x00, // (
+    0x00, 0x41, 0x22, 0x1C, 0x00, // )
+    0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
+    0x08, 0x08, 0x3E, 0x08, 0x08, // +
+    0x00, 0x50, 0x30, 0x00, 0x00, // ,
+    0x08, 0x08, 0x08, 0x08, 0x08, // -
+    0x00, 0x60, 0x60, 0x00, 0x00, // .
+    0x20, 0x10, 0x08, 0x04, 0x02, // /
+    0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
+    0x00, 0x42, 0x7F, 0x40, 0x00, // 1
+    0x42, 0x61, 0x51, 0x49, 0x46, // 2
+    0x21, 0x41, 0x45, 0x4B, 0x31, // 3
+    0x18, 0x14, 0x12, 0x7F, 0x10, // 4
+    0x27, 0x45, 0x45, 0x45, 0x39, // 5
+    0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
+    0x01, 0x71, 0x09, 0x05, 0x03, // 7
+    0x36, 0x49, 0x49, 0x49, 0x36, // 8
+    0x06, 0x49, 0x49, 0x29, 0x1E, // 9
+    0x00, 0x36, 0x36, 0x00, 0x00, // :
+    0x00, 0x56, 0x36, 0x00, 0x00, // ;
+    0x00, 0x08, 0x14, 0x22, 0x41, // <
+    0x14, 0x14, 0x14, 0x14, 0x14, // =
+    0x41, 0x22, 0x14, 0x08, 0x00, // >
+    0x02, 0x01, 0x51, 0x09, 0x06, // ?
+    0x32, 0x49, 0x79, 0x41, 0x3E, // @
+    0x7E, 0x11, 0x11, 0x11, 0x7E, // A
+    0x7F, 0x49, 0x49, 0x49, 0x36, // B
+    0x3E, 0x41, 0x41, 0x41, 0x22, // C
+    0x7F, 0x41, 0x41, 0x22, 0x1C, // D
+    0x7F, 0x49, 0x49, 0x49, 0x41, // E
+    0x7F, 0x09, 0x09, 0x01, 0x01, // F
+    0x3E, 0x41, 0x41, 0x51, 0x32, // G
+    0x7F, 0x08, 0x08, 0x08, 0x7F, // H
+    0x00, 0x41, 0x7F, 0x41, 0x00, // I
+    0x20, 0x40, 0x41, 0x3F, 0x01, // J
+    0x7F, 0x08, 0x14, 0x22, 0x41, // K
+    0x7F, 0x40, 0x40, 0x40, 0x40, // L
+    0x7F, 0x02, 0x04, 0x02, 0x7F, // M
+    0x7F, 0x04, 0x08, 0x10, 0x7F, // N
+    0x3E, 0x41, 0x41, 0x41, 0x3E, // O
+    0x7F, 0x09, 0x09, 0x09, 0x06, // P
+    0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
+    0x7F, 0x09, 0x19, 0x29, 0x46, // R
+    0x46, 0x49, 0x49, 0x49, 0x31, // S
+    0x01, 0x01, 0x7F, 0x01, 0x01, // T
+    0x3F, 0x40, 0x40, 0x40, 0x3F, // U
+    0x1F, 0x20, 0x40, 0x20, 0x1F, // V
+    0x7F, 0x20, 0x18, 0x20, 0x7F, // W
+    0x63, 0x14, 0x08, 0x14, 0x63, // X
+    0x03, 0x04, 0x78, 0x04, 0x03, // Y
+    0x61, 0x51, 0x49, 0x45, 0x43, // Z
+    0x00, 0x00, 0x7F, 0x41, 0x41, // [
+    0x02, 0x04, 0x08, 0x10, 0x20, // /
+    0x41, 0x41, 0x7F, 0x00, 0x00, // ]
+    0x04, 0x02, 0x01, 0x02, 0x04, // ^
+    0x40, 0x40, 0x40, 0x40, 0x40, // _
+    0x00, 0x01, 0x02, 0x04, 0x00, // `
+    0x20, 0x54, 0x54, 0x54, 0x78, // a
+    0x7F, 0x48, 0x44, 0x44, 0x38, // b
+    0x38, 0x44, 0x44, 0x44, 0x20, // c
+    0x38, 0x44, 0x44, 0x48, 0x7F, // d
+    0x38, 0x54, 0x54, 0x54, 0x18, // e
+    0x08, 0x7E, 0x09, 0x01, 0x02, // f
+    0x08, 0x14, 0x54, 0x54, 0x3C, // g
+    0x7F, 0x08, 0x04, 0x04, 0x78, // h
+    0x00, 0x44, 0x7D, 0x40, 0x00, // i
+    0x20, 0x40, 0x44, 0x3D, 0x00, // j
+    0x00, 0x7F, 0x10, 0x28, 0x44, // k
+    0x00, 0x41, 0x7F, 0x40, 0x00, // l
+    0x7C, 0x04, 0x18, 0x04, 0x78, // m
+    0x7C, 0x08, 0x04, 0x04, 0x78, // n
+    0x38, 0x44, 0x44, 0x44, 0x38, // o
+    0x7C, 0x14, 0x14, 0x14, 0x08, // p
+    0x08, 0x14, 0x14, 0x18, 0x7C, // q
+    0x7C, 0x08, 0x04, 0x04, 0x08, // r
+    0x48, 0x54, 0x54, 0x54, 0x20, // s
+    0x04, 0x3F, 0x44, 0x40, 0x20, // t
+    0x3C, 0x40, 0x40, 0x20, 0x7C, // u
+    0x1C, 0x20, 0x40, 0x20, 0x1C, // v
+    0x3C, 0x40, 0x30, 0x40, 0x3C, // w
+    0x44, 0x28, 0x10, 0x28, 0x44, // x
+    0x0C, 0x50, 0x50, 0x50, 0x3C, // y
+    0x44, 0x64, 0x54, 0x4C, 0x44, // z
+    0x00, 0x08, 0x36, 0x41, 0x00, // {
+    0x00, 0x00, 0x7F, 0x00, 0x00, // |
+    0x00, 0x41, 0x36, 0x08, 0x00, // }
+    0x08, 0x08, 0x2A, 0x1C, 0x08, // ->
+    0x08, 0x1C, 0x2A, 0x08, 0x08  // <-
+};
+
+SG12864A::SG12864A(PinName di,
+                   PinName rw,
+                   PinName en,
+                   PinName db0,
+                   PinName db1,
+                   PinName db2,
+                   PinName db3,
+                   PinName db4,
+                   PinName db5,
+                   PinName db6,
+                   PinName db7,
+                   PinName cs1,
+                   PinName cs2,
+                   PinName res)
+        :
+        ioDI(di),
+        ioRW(rw),
+        ioEN(en),
+        ioDB(db0, db1, db2, db3, db4, db5, db6, db7),
+        ioCS1(cs1),
+        ioCS2(cs2),
+        ioRES(res) {
+    bufferClear();
+    setDirectionToWrite();
+}
+
+SG12864A::~SG12864A() {
+}
+
+void SG12864A::bufferPush(void) {
+    for (uint8_t i = 0; i < PAGES; i++) {
+        // CS1
+        setPageAddress(SG12864A::CS1, i);
+        setColumnAddress(SG12864A::CS1, 0);
+        for (uint8_t j = 0; j < COLUMNS; j++) {
+            writeData(CS1, buffer[0 + ((COLUMNS * 2) * i) + j]);
+        }
+        // CS2
+        setPageAddress(SG12864A::CS2, i);
+        setColumnAddress(SG12864A::CS2, 0);
+        for (uint8_t j = 0; j < COLUMNS; j++) {
+            writeData(CS2, buffer[COLUMNS + ((COLUMNS * 2) * i) + j]);
+        }
+    }
+}
+
+void SG12864A::bufferPull(void) {
+}
+
+void SG12864A::bufferClear(bool reverse) {
+    for (int i = 0; i < sizeof(buffer); i++) {
+        if (reverse) {
+            buffer[i] = 0xFF;
+        } else {
+            buffer[i] = 0x00;
+        }
+    }
+}
+
+void SG12864A::bufferDrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) {
+    /*
+     * Bresenham's line algorithm
+     */
+    bool steep = abs(y2 - y1) > abs(x2 - x1);
+    if (steep) {
+        swap(x1, y1);
+        swap(x2, y2);
+    }
+    if (x1 > x2) {
+        swap(x1, x2);
+        swap(y1, y2);
+    }
+    int deltax = x2 - x1;
+    int deltay = abs(y2 - y1);
+    int error = deltax / 2;
+    int ystep;
+    int y = y1;
+    if (y1 < y2) {
+        ystep = 1;
+    } else {
+        ystep = -1;
+    }
+    for (int x = x1; x <= x2; x++) {
+        if (steep) {
+            if (reverse) {
+                unsetPixel(y, x);
+            } else {
+                setPixel(y, x);
+            }
+        } else {
+            if (reverse) {
+                unsetPixel(x, y);
+            } else {
+                setPixel(x, y);
+            }
+        }
+        error = error - deltay;
+        if (error < 0) {
+            y = y + ystep;
+            error = error + deltax;
+        }
+    }
+}
+
+void SG12864A::bufferDrawBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) {
+    for (int x = x1; x <= x2; x++) {
+        if (reverse) {
+            unsetPixel(x, y1);
+            unsetPixel(x, y2);
+        } else {
+            setPixel(x, y1);
+            setPixel(x, y2);
+        }
+    }
+    for (int y = y1; y <= y2; y++) {
+        if (reverse) {
+            unsetPixel(x1, y);
+            unsetPixel(x2, y);
+        } else {
+            setPixel(x1, y);
+            setPixel(x2, y);
+        }
+    }
+}
+
+void SG12864A::bufferFillBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) {
+    for (int x = x1; x <= x2; x++) {
+        for (int y = y1; y <= y2; y++) {
+            if (reverse) {
+                unsetPixel(x, y);
+            } else {
+                setPixel(x, y);
+            }
+        }
+    }
+}
+
+void SG12864A::bufferDrawString(uint8_t x, uint8_t y, char * str, bool reverse) {
+    char *p = str;
+    int cnt = 0;
+    while (*p) {
+        bufferDrawChar(x + (FONT_X * cnt), y, *p, reverse);
+        p++;
+        cnt++;
+    }
+}
+
+void SG12864A::bufferDrawChar(uint8_t x, uint8_t y, char c, bool reverse) {
+    if ((FONT_MIN_CODE <= c) &&(c <= FONT_MAX_CODE)) {
+        int aofs = (c - FONT_MIN_CODE) * FONT_X;
+        for (int i = 0; i < FONT_X; i++) {
+            uint8_t pat = font5x7_data[aofs + i];
+            for (int j = 0; j < FONT_Y; j++) {
+                if (pat & (1 << j)) {
+                    if (reverse) {
+                        unsetPixel(x + i, y + j);
+                    } else {
+                        setPixel(x + i, y + j);
+                    }
+                } else {
+                    if (reverse) {
+                        setPixel(x + i, y + j);
+                    } else {
+                        unsetPixel(x + i, y + j);
+                    }
+                }
+            }
+        }
+    } else {
+        for (int i = 0; i < FONT_X; i++) {
+            uint8_t pat = (i % 2) ? 0x55 : 0xAA;
+            for (int j = 0; j < FONT_Y; j++) {
+                if (pat & (1 << j)) {
+                    if (reverse) {
+                        unsetPixel(x + i, y + j);
+                    } else {
+                        setPixel(x + i, y + j);
+                    }
+                } else {
+                    if (reverse) {
+                        setPixel(x + i, y + j);
+                    } else {
+                        unsetPixel(x + i, y + j);
+                    }
+                }
+            }
+        }
+    }
+}
+
+void SG12864A::bufferDrawCheckbox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state, bool reverse) {
+    bufferDrawBox(x1, y1, x2, y2, reverse);
+    if (state) {
+        bufferDrawLine(x1, y1, x2, y2, reverse);
+        bufferDrawLine(x1, y2, x2, y1, reverse);
+    }
+}
+
+void SG12864A::bufferDrawProgressbar(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, int min, int max, int value, bool reverse) {
+    bufferDrawBox(x1, y1, x2, y2, reverse);
+    if ((value < min) || (max < value)) {
+        return;
+    }
+    int tmp_max = max - min;
+    int tmp_val = value - min;
+    int pix = ((x2 - x1) * tmp_val) / tmp_max;
+    bufferFillBox(x1 + 1, y1 + 1, x1 + pix - 1, y2 - 1, reverse);
+}
+
+/**
+ * High Level Interface.
+ *
+ * Reset display module.
+ */
+void SG12864A::reset(void) {
+    reset(true);
+    wait_ms(200);
+    reset(false);
+    wait_ms(200);
+
+    setDisplayOnOff(SG12864A::CS1, true);
+    setDisplayOnOff(SG12864A::CS2, true);
+    setDisplayStartLine(SG12864A::CS1, 0);
+    setDisplayStartLine(SG12864A::CS2, 0);
+    setPageAddress(SG12864A::CS1, 0);
+    setPageAddress(SG12864A::CS2, 0);
+    setColumnAddress(SG12864A::CS1, 0);
+    setColumnAddress(SG12864A::CS2, 0);
+}
+
+/**
+ * High Level Interface.
+ *
+ * Clear display module.
+ */
+void SG12864A::clear(void) {
+    for (uint8_t page = 0; page < PAGES; page++) {
+        for (uint8_t column = 0; column < COLUMNS; column++) {
+            // CS1
+            setPageAddress(SG12864A::CS1, page);
+            setColumnAddress(SG12864A::CS1, column);
+            writeData(CS1, 0x00);
+            // CS2
+            setPageAddress(SG12864A::CS2, page);
+            setColumnAddress(SG12864A::CS2, column);
+            writeData(CS2, 0x00);
+        }
+    }
+    // CS1
+    setPageAddress(SG12864A::CS1, 0);
+    setColumnAddress(SG12864A::CS1, 0);
+    writeData(CS1, 0x00);
+    // CS2
+    setPageAddress(SG12864A::CS2, 0);
+    setColumnAddress(SG12864A::CS2, 0);
+    writeData(CS2, 0x00);
+}
+
+/**
+ * Middle Level Interface.
+ *
+ * Set display on/off.
+ *
+ * @param t Target (CS1, CS2).
+ * @param on ON/OFF (true, false).
+ */
+void SG12864A::setDisplayOnOff(Target t, bool on) {
+    setDirectionToWrite();
+    uint8_t c = 0x3e | (on ? 0x01 : 0x00);
+    write(t, SG12864A::Instruction, c);
+    wait_us(1);
+}
+
+/**
+ * Middle Level Interface.
+ *
+ * Set display start line.
+ *
+ * @param t Target (CS1, CS2).
+ * @param addr Display start line (0-63).
+ */
+void SG12864A::setDisplayStartLine(Target t, uint8_t addr) {
+    setDirectionToWrite();
+    uint8_t c = 0xc0 | (addr & 0x3f);
+    write(t, SG12864A::Instruction, c);
+    wait_us(1);
+}
+
+/**
+ * Middle Level Interface.
+ *
+ * Set page address.
+ *
+ * @param t Target (CS1, CS2).
+ * @param addr Page address(0-7).
+ */
+void SG12864A::setPageAddress(Target t, uint8_t addr) {
+    setDirectionToWrite();
+    uint8_t c = 0xb8 | (addr & 0x07);
+    write(t, SG12864A::Instruction, c);
+    wait_us(1);
+}
+
+/**
+ * Middle Level Interface.
+ *
+ * Set column address.
+ *
+ * @param t Target. (CS1, CS2)
+ * @param addr Column address (0-63).
+ */
+void SG12864A::setColumnAddress(Target t, uint8_t addr) {
+    setDirectionToWrite();
+    uint8_t c = 0x40 | (addr & 0x3f);
+    write(t, SG12864A::Instruction, c);
+    wait_us(1);
+}
+
+/**
+ * Middle Level Interface.
+ */
+void SG12864A::readStatus(Target t, uint8_t *c) {
+    setDirectionToRead();
+    read(t, SG12864A::Instruction, c);
+    wait_us(1);
+}
+
+/**
+ * Middle Level Interface.
+ */
+void SG12864A::writeData(Target t, uint8_t c) {
+    setDirectionToWrite();
+    write(t, SG12864A::Data, c);
+    wait_us(1);
+}
+
+/**
+ * Middle Level Interface.
+ */
+void SG12864A::readData(Target t, uint8_t *c) {
+    setDirectionToRead();
+    read(t, SG12864A::Data, c);
+    wait_us(1);
+}
+
+/**
+ * Low Level Interface.
+ */
+void SG12864A::setDirectionToRead() {
+    ioDB.input();
+    ioRW = 1;
+}
+
+/**
+ * Low Level Interface.
+ */
+void SG12864A::setDirectionToWrite() {
+    ioDB.output();
+    ioRW = 0;
+}
+
+/**
+ * Low Level Interface.
+ */
+void SG12864A::write(Target t, Mode m, uint8_t c) {
+    switch (t) {
+        case CS1:
+            ioCS1 = 1;
+            ioCS2 = 0;
+            break;
+        case CS2:
+            ioCS1 = 0;
+            ioCS2 = 1;
+            break;
+    }
+    switch (m) {
+        case Data:
+            ioDI = 1;
+            break;
+        case Instruction:
+            ioDI = 0;
+            break;
+    }
+    ioDB = c;
+    wait_us(1);
+    ioEN = 1;
+    wait_us(1);
+    ioEN = 0;
+    wait_us(5);
+}
+
+/**
+ * Low Level Interface.
+ */
+void SG12864A::read(Target t, Mode m, uint8_t *c) {
+    // TODO
+}
+
+/**
+ * Low Level Interface.
+ */
+void SG12864A::reset(bool b) {
+    if (b) {
+        ioRES = 0;
+    } else {
+        ioRES = 1;
+    }
+}
--- a/SG12864A.h	Tue Aug 10 12:36:05 2010 +0000
+++ b/SG12864A.h	Tue Aug 10 12:52:53 2010 +0000
@@ -1,318 +1,317 @@
-/**
- * SG12864A Graphics LCD module driver class (Version 0.0.1)
- *
- * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
- * http://shinta.main.jp/
- *
- * See also ...
- * http://mbed.org/users/shintamainjp/notebook/sg12864asunlike-display-graphics-lcd-driver/
- */
-
-#ifndef _SG12864A_H_
-#define _SG12864A_H_
-
-#include "mbed.h"
-
-/**
- * SG12864A Graphics LCD module driver class.
- */
-class SG12864A {
-public:
-
-    /**
-     * Create.
-     *
-     * @param di D-/I (H:Instruction, L:Data)
-     * @param rw R/W- (H:Read, L:Write)
-     * @param en Enable signal
-     * @param db0 Data bus line bit-0.
-     * @param db1 Data bus line bit-1.
-     * @param db2 Data bus line bit-2.
-     * @param db3 Data bus line bit-3.
-     * @param db4 Data bus line bit-4.
-     * @param db5 Data bus line bit-5.
-     * @param db6 Data bus line bit-6.
-     * @param db7 Data bus line bit-7.
-     * @param cs1 Chip select signal for IC1.
-     * @param cs2 Chip select signal for IC2.
-     * @param res Reset signal.
-     */
-    SG12864A(
-        PinName di,
-        PinName rw,
-        PinName en,
-        PinName db0,
-        PinName db1,
-        PinName db2,
-        PinName db3,
-        PinName db4,
-        PinName db5,
-        PinName db6,
-        PinName db7,
-        PinName cs1,
-        PinName cs2,
-        PinName res);
-    /**
-     * Destroy.
-     */
-    ~SG12864A();
-
-    /**
-     * Target of a chip.
-     */
-    enum Target {
-        CS1,
-        CS2
-    };
-
-    /*
-     * =======================================================
-     * High Level Interfaces.
-     * =======================================================
-     */
-
-    /**
-     * Push images from a internal buffer.
-     */
-    void bufferPush(void);
-
-    /**
-     * Pull images to a internal buffer.
-     */
-    void bufferPull(void);
-
-    /**
-     * Clear a internal buffer images.
-     *
-     * @param reverse True if images are reversed.
-     */
-    void bufferClear(bool reverse = false);
-
-    /**
-     * Draw a line to a internal buffer.
-     *
-     * @param x1 Starting point at x-axis.
-     * @param y1 Starting point at y-axis.
-     * @param x2 Ending point at x-axis.
-     * @param y2 Ending point at y-axis.
-     * @param reverse True if images are reversed.
-     */
-    void bufferDrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse = false);
-
-    /**
-     * Draw a box to a internal buffer.
-     *
-     * @param x1 Starting point at x-axis.
-     * @param y1 Starting point at y-axis.
-     * @param x2 Ending point at x-axis.
-     * @param y2 Ending point at y-axis.
-     * @param reverse True if images are reversed.
-     */
-    void bufferDrawBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse = false);
-
-    /**
-     * Fill a box to a internal buffer.
-     *
-     * @param x1 Starting point at x-axis.
-     * @param y1 Starting point at y-axis.
-     * @param x2 Ending point at x-axis.
-     * @param y2 Ending point at y-axis.
-     * @param reverse True if images are reversed.
-     */
-    void bufferFillBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse = false);
-
-    /**
-     * Draw a text string to a internal buffer.
-     * The font size is 5x7 dots.
-     *
-     * @param x Starting point at x-axis.
-     * @param y Starting point at y-axis.
-     * @param str Text string. (NULL terminate.)
-     * @param reverse True if images are reversed.
-     */
-    void bufferDrawString(uint8_t x, uint8_t y, char * str, bool reverse = false);
-
-    /**
-     * Draw a character to a internal buffer.
-     * The font size is 5x7 dots.
-     *
-     * @param x Starting point at x-axis.
-     * @param y Starting point at y-axis.
-     * @param c A character.
-     * @param reverse True if images are reversed.
-     */
-    void bufferDrawChar(uint8_t x, uint8_t y, char c, bool reverse = false);
-
-    /**
-     * Draw a checkbox to a internal buffer.
-     *
-     * @param x1 Starting point at x-axis.
-     * @param y1 Starting point at y-axis.
-     * @param x2 Ending point at x-axis.
-     * @param y2 Ending point at y-axis.
-     * @param state True if state is checked.
-     * @param reverse True if images are reversed.
-     */
-    void bufferDrawCheckbox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state, bool reverse = false);
-
-    /**
-     * Draw a progressbar to a internal buffer.
-     *
-     * @param x1 Starting point at x-axis.
-     * @param y1 Starting point at y-axis.
-     * @param x2 Ending point at x-axis.
-     * @param y2 Ending point at y-axis.
-     * @param min Minimum value on a scale.
-     * @param max Maximum value on a scale.
-     * @param value Current value on a scale.
-     * @param state True if state is checked.
-     * @param reverse True if images are reversed.
-     */
-    void bufferDrawProgressbar(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, int min, int max, int value, bool horizontal = false, bool reverse = false);
-
-    /*
-     * High Level Interfaces.
-     */
-
-    /**
-     * Reset module.
-     */
-    void reset(void);
-
-    /**
-     * Clear display.
-     */
-    void clear(void);
-
-    /*
-     * =======================================================
-     * Middle Level Interfaces.
-     * =======================================================
-     */
-
-    /**
-     * Set display ON/OFF.
-     *
-     * @param t Target.
-     * @param on True if the display is ON.
-     */
-    void setDisplayOnOff(Target t, bool on);
-    
-    /**
-     * Set display start line.
-     *
-     * @param t Target.
-     * @param displayStartLine Start line number.
-     */
-    void setDisplayStartLine(Target t, uint8_t displayStartLine);
-    
-    /**
-     * Set page address.
-     *
-     * @param t Target.
-     * @param addr Address.
-     */
-    void setPageAddress(Target t, uint8_t addr);
-
-    /**
-     * Set column address.
-     *
-     * @param t Target.
-     * @param addr Address.
-     */
-    void setColumnAddress(Target t, uint8_t addr);
-
-    /**
-     * Read status.
-     *
-     * @param t Target.
-     * @param c Status.
-     */
-    void readStatus(Target t, uint8_t *c);
-
-    /**
-     * Write data.
-     *
-     * @param t Target.
-     * @param c Status.
-     */
-    void writeData(Target t, uint8_t c);
-
-    /**
-     * Read data.
-     *
-     * @param t Target.
-     * @param c Status.
-     */
-    void readData(Target t, uint8_t *c);
-
-    static const int PIXEL_X = 128;
-    static const int PIXEL_Y = 64;
-    static const uint8_t FONT_X = 5;
-    static const uint8_t FONT_Y = 7;
-private:
-    static const int PAGES = 8;
-    static const int COLUMNS = 64;
-    static const uint16_t FONT_MIN_CODE = 0x20;
-    static const uint16_t FONT_MAX_CODE = 0x7F;
-    static const uint8_t font5x7_data[];
-    uint8_t buffer[PAGES * COLUMNS * 2];
-    DigitalOut ioDI;
-    DigitalOut ioRW;
-    DigitalOut ioEN;
-    BusInOut ioDB;
-    DigitalOut ioCS1;
-    DigitalOut ioCS2;
-    DigitalOut ioRES;
-
-    /**
-     * Mode of a write data.
-     */
-    enum Mode {
-        Data,
-        Instruction
-    };
-
-    /*
-     * =======================================================
-     * Low Level Interfaces.
-     * =======================================================
-     */
-
-    /**
-     * Set I/O direction to read.
-     */
-    void setDirectionToRead();
-
-    /**
-     * Set I/O direction to write.
-     */
-    void setDirectionToWrite();
-
-    /**
-     * Write data.
-     *
-     * @param t Target.
-     * @param m Mode.
-     * @param c Data.
-     */
-    void write(Target t, Mode m, uint8_t c);
-
-    /**
-     * Read data.
-     *
-     * @param t Target.
-     * @param m Mode.
-     * @param c Data.
-     */
-    void read(Target t, Mode m, uint8_t *c);
-
-    /**
-     * Reset.
-     *
-     * @param b True if reset active.
-     */
-    void reset(bool b);
-};
-
-#endif
+/**
+ * SG12864A Graphics LCD module driver class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ *
+ * See also ...
+ * http://mbed.org/users/shintamainjp/notebook/sg12864asunlike-display-graphics-lcd-driver/
+ */
+
+#ifndef _SG12864A_H_
+#define _SG12864A_H_
+
+#include "mbed.h"
+
+/**
+ * SG12864A Graphics LCD module driver class.
+ */
+class SG12864A {
+public:
+
+    /**
+     * Create.
+     *
+     * @param di D-/I (H:Instruction, L:Data)
+     * @param rw R/W- (H:Read, L:Write)
+     * @param en Enable signal
+     * @param db0 Data bus line bit-0.
+     * @param db1 Data bus line bit-1.
+     * @param db2 Data bus line bit-2.
+     * @param db3 Data bus line bit-3.
+     * @param db4 Data bus line bit-4.
+     * @param db5 Data bus line bit-5.
+     * @param db6 Data bus line bit-6.
+     * @param db7 Data bus line bit-7.
+     * @param cs1 Chip select signal for IC1.
+     * @param cs2 Chip select signal for IC2.
+     * @param res Reset signal.
+     */
+    SG12864A(
+        PinName di,
+        PinName rw,
+        PinName en,
+        PinName db0,
+        PinName db1,
+        PinName db2,
+        PinName db3,
+        PinName db4,
+        PinName db5,
+        PinName db6,
+        PinName db7,
+        PinName cs1,
+        PinName cs2,
+        PinName res);
+    /**
+     * Destroy.
+     */
+    ~SG12864A();
+
+    /**
+     * Target of a chip.
+     */
+    enum Target {
+        CS1,
+        CS2
+    };
+
+    /*
+     * =======================================================
+     * High Level Interfaces.
+     * =======================================================
+     */
+
+    /**
+     * Push images from a internal buffer.
+     */
+    void bufferPush(void);
+
+    /**
+     * Pull images to a internal buffer.
+     */
+    void bufferPull(void);
+
+    /**
+     * Clear a internal buffer images.
+     *
+     * @param reverse True if images are reversed.
+     */
+    void bufferClear(bool reverse = false);
+
+    /**
+     * Draw a line to a internal buffer.
+     *
+     * @param x1 Starting point at x-axis.
+     * @param y1 Starting point at y-axis.
+     * @param x2 Ending point at x-axis.
+     * @param y2 Ending point at y-axis.
+     * @param reverse True if images are reversed.
+     */
+    void bufferDrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse = false);
+
+    /**
+     * Draw a box to a internal buffer.
+     *
+     * @param x1 Starting point at x-axis.
+     * @param y1 Starting point at y-axis.
+     * @param x2 Ending point at x-axis.
+     * @param y2 Ending point at y-axis.
+     * @param reverse True if images are reversed.
+     */
+    void bufferDrawBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse = false);
+
+    /**
+     * Fill a box to a internal buffer.
+     *
+     * @param x1 Starting point at x-axis.
+     * @param y1 Starting point at y-axis.
+     * @param x2 Ending point at x-axis.
+     * @param y2 Ending point at y-axis.
+     * @param reverse True if images are reversed.
+     */
+    void bufferFillBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse = false);
+
+    /**
+     * Draw a text string to a internal buffer.
+     * The font size is 5x7 dots.
+     *
+     * @param x Starting point at x-axis.
+     * @param y Starting point at y-axis.
+     * @param str Text string. (NULL terminate.)
+     * @param reverse True if images are reversed.
+     */
+    void bufferDrawString(uint8_t x, uint8_t y, char * str, bool reverse = false);
+
+    /**
+     * Draw a character to a internal buffer.
+     * The font size is 5x7 dots.
+     *
+     * @param x Starting point at x-axis.
+     * @param y Starting point at y-axis.
+     * @param c A character.
+     * @param reverse True if images are reversed.
+     */
+    void bufferDrawChar(uint8_t x, uint8_t y, char c, bool reverse = false);
+
+    /**
+     * Draw a checkbox to a internal buffer.
+     *
+     * @param x1 Starting point at x-axis.
+     * @param y1 Starting point at y-axis.
+     * @param x2 Ending point at x-axis.
+     * @param y2 Ending point at y-axis.
+     * @param state True if state is checked.
+     * @param reverse True if images are reversed.
+     */
+    void bufferDrawCheckbox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state, bool reverse = false);
+
+    /**
+     * Draw a progressbar to a internal buffer.
+     *
+     * @param x1 Starting point at x-axis.
+     * @param y1 Starting point at y-axis.
+     * @param x2 Ending point at x-axis.
+     * @param y2 Ending point at y-axis.
+     * @param min Minimum value on a scale.
+     * @param max Maximum value on a scale.
+     * @param value Current value on a scale.
+     * @param reverse True if images are reversed.
+     */
+    void bufferDrawProgressbar(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, int min, int max, int value, bool reverse = false);
+
+    /*
+     * High Level Interfaces.
+     */
+
+    /**
+     * Reset module.
+     */
+    void reset(void);
+
+    /**
+     * Clear display.
+     */
+    void clear(void);
+
+    /*
+     * =======================================================
+     * Middle Level Interfaces.
+     * =======================================================
+     */
+
+    /**
+     * Set display ON/OFF.
+     *
+     * @param t Target.
+     * @param on True if the display is ON.
+     */
+    void setDisplayOnOff(Target t, bool on);
+    
+    /**
+     * Set display start line.
+     *
+     * @param t Target.
+     * @param displayStartLine Start line number.
+     */
+    void setDisplayStartLine(Target t, uint8_t displayStartLine);
+    
+    /**
+     * Set page address.
+     *
+     * @param t Target.
+     * @param addr Address.
+     */
+    void setPageAddress(Target t, uint8_t addr);
+
+    /**
+     * Set column address.
+     *
+     * @param t Target.
+     * @param addr Address.
+     */
+    void setColumnAddress(Target t, uint8_t addr);
+
+    /**
+     * Read status.
+     *
+     * @param t Target.
+     * @param c Status.
+     */
+    void readStatus(Target t, uint8_t *c);
+
+    /**
+     * Write data.
+     *
+     * @param t Target.
+     * @param c Status.
+     */
+    void writeData(Target t, uint8_t c);
+
+    /**
+     * Read data.
+     *
+     * @param t Target.
+     * @param c Status.
+     */
+    void readData(Target t, uint8_t *c);
+
+    static const int PIXEL_X = 128;
+    static const int PIXEL_Y = 64;
+    static const uint8_t FONT_X = 5;
+    static const uint8_t FONT_Y = 7;
+private:
+    static const int PAGES = 8;
+    static const int COLUMNS = 64;
+    static const uint16_t FONT_MIN_CODE = 0x20;
+    static const uint16_t FONT_MAX_CODE = 0x7F;
+    static const uint8_t font5x7_data[];
+    uint8_t buffer[PAGES * COLUMNS * 2];
+    DigitalOut ioDI;
+    DigitalOut ioRW;
+    DigitalOut ioEN;
+    BusInOut ioDB;
+    DigitalOut ioCS1;
+    DigitalOut ioCS2;
+    DigitalOut ioRES;
+
+    /**
+     * Mode of a write data.
+     */
+    enum Mode {
+        Data,
+        Instruction
+    };
+
+    /*
+     * =======================================================
+     * Low Level Interfaces.
+     * =======================================================
+     */
+
+    /**
+     * Set I/O direction to read.
+     */
+    void setDirectionToRead();
+
+    /**
+     * Set I/O direction to write.
+     */
+    void setDirectionToWrite();
+
+    /**
+     * Write data.
+     *
+     * @param t Target.
+     * @param m Mode.
+     * @param c Data.
+     */
+    void write(Target t, Mode m, uint8_t c);
+
+    /**
+     * Read data.
+     *
+     * @param t Target.
+     * @param m Mode.
+     * @param c Data.
+     */
+    void read(Target t, Mode m, uint8_t *c);
+
+    /**
+     * Reset.
+     *
+     * @param b True if reset active.
+     */
+    void reset(bool b);
+};
+
+#endif
--- a/main.cpp	Tue Aug 10 12:36:05 2010 +0000
+++ b/main.cpp	Tue Aug 10 12:52:53 2010 +0000
@@ -1,116 +1,116 @@
-/**
- * sample program for SG12864A Graphics LCD module driver class (Version 0.0.1)
- *
- * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
- * http://shinta.main.jp/
- *
- * See also ...
- * http://mbed.org/users/shintamainjp/notebook/sg12864asunlike-display-graphics-lcd-driver/
- */
-
-#include "mbed.h"
-#include "SG12864A.h"
-
-int main() {
-
-    SG12864A lcd(p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18);
-#if 0
-    lcd.clear();
-    lcd.reset();
-
-    {
-        static const int pages = 8;
-        static const int columns = 64;
-        for (int i = 0; i < pages; i++) {
-            lcd.setPageAddress(SG12864A::CS1, i);
-            lcd.setPageAddress(SG12864A::CS2, i);
-            for (int j = 0; j < columns; j++) {
-                uint8_t n = 1 << (j % 8);
-                lcd.setColumnAddress(SG12864A::CS1, j);
-                lcd.setColumnAddress(SG12864A::CS2, j);
-                lcd.writeData(SG12864A::CS1, n);
-                lcd.writeData(SG12864A::CS2, n);
-            }
-        }
-    }
-
-    uint8_t n = 0;
-    while (1) {
-        lcd.setDisplayStartLine(SG12864A::CS1, n);
-        lcd.setDisplayStartLine(SG12864A::CS2, n);
-        n++;
-        wait_ms(100);
-    }
-#else
-    lcd.clear();
-    lcd.reset();
-    bool reverse = false;
-    while (1) {
-        //
-        lcd.bufferClear(reverse);
-        lcd.bufferDrawLine(0, 0, SG12864A::PIXEL_X - 1, SG12864A::PIXEL_Y - 1, reverse);
-        lcd.bufferDrawLine(0, SG12864A::PIXEL_Y - 1, SG12864A::PIXEL_X - 1, 0, reverse);
-        lcd.bufferDrawString(1, 1, "This is a test #1.\b", reverse);
-        lcd.bufferDrawCheckbox(50, 50, 60, 60, true, reverse);
-        lcd.bufferPush();
-        wait_ms(1000);
-
-        //
-        lcd.bufferClear(reverse);
-        lcd.bufferDrawBox(0, 0, SG12864A::PIXEL_X - 1, SG12864A::PIXEL_Y - 1, reverse);
-        lcd.bufferDrawString(1, 2, "This is a test #2.\b", reverse);
-        lcd.bufferDrawCheckbox(50, 50, 60, 60, false, reverse);
-        lcd.bufferPush();
-        wait_ms(1000);
-
-#if 0
-        //
-        lcd.bufferClear(reverse);
-        lcd.bufferFillBox(0, 0, SG12864A::PIXEL_X - 1, SG12864A::PIXEL_Y - 1, reverse);
-        lcd.bufferDrawString(1, 3, "This is a test #3.\b", reverse);
-        lcd.bufferDrawCheckbox(50, 50, 60, 60, true, reverse);
-        lcd.bufferPush();
-        wait_ms(1000);
-#endif
-
-        //
-        {
-            lcd.bufferClear(reverse);
-            int min = 0;
-            int max = 100;
-            for (int i = min; i <= max; i++) {
-                lcd.bufferDrawProgressbar(10, 10, 118, 20, min, max, i, true, reverse);
-                lcd.bufferPush();
-                wait_ms(2);
-            }
-        }
-
-        //
-        {
-            lcd.bufferClear(reverse);
-            int min = -100;
-            int max = 100;
-            for (int i = min; i <= max; i++) {
-                lcd.bufferDrawProgressbar(10, 10, 118, 20, min, max, i, true, reverse);
-                lcd.bufferPush();
-                wait_ms(2);
-            }
-        }
-
-        //
-        {
-            lcd.bufferClear(reverse);
-            int min = 100;
-            int max = 600;
-            for (int i = min; i <= max; i++) {
-                lcd.bufferDrawProgressbar(10, 10, 118, 20, min, max, i, true, reverse);
-                lcd.bufferPush();
-                wait_ms(2);
-            }
-        }
-
-        //
-        reverse = !reverse;
-    }
-#endif
-}
+/**
+ * sample program for SG12864A Graphics LCD module driver class (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ *
+ * See also ...
+ * http://mbed.org/users/shintamainjp/notebook/sg12864asunlike-display-graphics-lcd-driver/
+ */
+
+#include "mbed.h"
+#include "SG12864A.h"
+
+int main() {
+
+    SG12864A lcd(p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18);
+#if 0
+    lcd.clear();
+    lcd.reset();
+
+    {
+        static const int pages = 8;
+        static const int columns = 64;
+        for (int i = 0; i < pages; i++) {
+            lcd.setPageAddress(SG12864A::CS1, i);
+            lcd.setPageAddress(SG12864A::CS2, i);
+            for (int j = 0; j < columns; j++) {
+                uint8_t n = 1 << (j % 8);
+                lcd.setColumnAddress(SG12864A::CS1, j);
+                lcd.setColumnAddress(SG12864A::CS2, j);
+                lcd.writeData(SG12864A::CS1, n);
+                lcd.writeData(SG12864A::CS2, n);
+            }
+        }
+    }
+
+    uint8_t n = 0;
+    while (1) {
+        lcd.setDisplayStartLine(SG12864A::CS1, n);
+        lcd.setDisplayStartLine(SG12864A::CS2, n);
+        n++;
+        wait_ms(100);
+    }
+#else
+    lcd.clear();
+    lcd.reset();
+    bool reverse = false;
+    while (1) {
+        //
+        lcd.bufferClear(reverse);
+        lcd.bufferDrawLine(0, 0, SG12864A::PIXEL_X - 1, SG12864A::PIXEL_Y - 1, reverse);
+        lcd.bufferDrawLine(0, SG12864A::PIXEL_Y - 1, SG12864A::PIXEL_X - 1, 0, reverse);
+        lcd.bufferDrawString(1, 1, "This is a test #1.\b", reverse);
+        lcd.bufferDrawCheckbox(50, 50, 60, 60, true, reverse);
+        lcd.bufferPush();
+        wait_ms(1000);
+
+        //
+        lcd.bufferClear(reverse);
+        lcd.bufferDrawBox(0, 0, SG12864A::PIXEL_X - 1, SG12864A::PIXEL_Y - 1, reverse);
+        lcd.bufferDrawString(1, 2, "This is a test #2.\b", reverse);
+        lcd.bufferDrawCheckbox(50, 50, 60, 60, false, reverse);
+        lcd.bufferPush();
+        wait_ms(1000);
+
+#if 0
+        //
+        lcd.bufferClear(reverse);
+        lcd.bufferFillBox(0, 0, SG12864A::PIXEL_X - 1, SG12864A::PIXEL_Y - 1, reverse);
+        lcd.bufferDrawString(1, 3, "This is a test #3.\b", reverse);
+        lcd.bufferDrawCheckbox(50, 50, 60, 60, true, reverse);
+        lcd.bufferPush();
+        wait_ms(1000);
+#endif
+
+        //
+        {
+            lcd.bufferClear(reverse);
+            int min = 0;
+            int max = 100;
+            for (int i = min; i <= max; i++) {
+                lcd.bufferDrawProgressbar(10, 10, 118, 20, min, max, i, reverse);
+                lcd.bufferPush();
+                wait_ms(2);
+            }
+        }
+
+        //
+        {
+            lcd.bufferClear(reverse);
+            int min = -100;
+            int max = 100;
+            for (int i = min; i <= max; i++) {
+                lcd.bufferDrawProgressbar(10, 10, 118, 20, min, max, i, reverse);
+                lcd.bufferPush();
+                wait_ms(2);
+            }
+        }
+
+        //
+        {
+            lcd.bufferClear(reverse);
+            int min = 100;
+            int max = 600;
+            for (int i = min; i <= max; i++) {
+                lcd.bufferDrawProgressbar(10, 10, 118, 20, min, max, i, reverse);
+                lcd.bufferPush();
+                wait_ms(2);
+            }
+        }
+
+        //
+        reverse = !reverse;
+    }
+#endif
+}