Graphic OLED 100x16 pixels interface

Dependents:   mbed_nicovideo_search_api mbed_recent_nicovideo_display_pub

/media/uploads/va009039/graphicoled_1.jpg

Revision:
3:a6650dd2dbc8
Parent:
2:337a2655f815
--- a/GraphicOLED.cpp	Mon Aug 04 06:17:36 2014 +0000
+++ b/GraphicOLED.cpp	Tue Aug 12 01:47:43 2014 +0000
@@ -1,53 +1,35 @@
 // GraphicOLED.cpp
 #include "GraphicOLED.h"
-#include <ctype.h>
 
-extern void font_4x8(uint8_t buf[], int i);
-extern void font_8x8(uint8_t buf[], int i);
+extern void font_4x8(uint8_t buf[], int c); // misaki_4x8_jis201.cpp
+extern void font_8x8(uint8_t buf[], uint32_t unicode); // misaki_8x8_unicode.cpp
 
 GraphicOLED::GraphicOLED(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7) :  _rs(rs), _e(e), _d(d4, d5, d6, d7) {
     _e  = 1;
     _rs = 0;            // command mode
 
-    wait_ms(15);        // Wait 15ms to ensure powered up
+    wait_ms(500);       // Wait For Stabilization 500ms
 
-    // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
-    for (int i=0; i<3; i++) {
-        writeByte(0x3);
-        wait_ms(2);     // this command takes 1.64ms, so wait for it
-    }
-    writeByte(0x2);     // 4-bit mode
-    wait_us(40);        // most instructions take 40us
-
-    //writeCommand(0x28); // Function set 001 BW N F - -
-    //writeCommand(0x0C);
-    //writeCommand(0x6);  // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
-    //cls();
-    
-    wait_ms(500); // wait 500ms
-    writeCommand(0x00); // 0x0 x 5
+    writeCommand(0x00); // 0x0 x 5, sync 4bit-mode
     writeCommand(0x00);
     writeCommand(0x02); // function set
-    writeCommand(0x28); // N=1
+    writeCommand(0x28); // N=1 2-line display
     writeCommand(0x0c); // D=1 display on
     writeCommand(0x14); // S/C=0 R/L=1
     writeCommand(0x1f); // G/C=1 graphic mode
-    _kanji_flag = false;
+
+    _uni_len = 0;
 }
 
-void GraphicOLED::g_write(uint8_t pat, int x, int y)
-{
-    writeCommand(0x40+y); // y position
-    writeCommand(0x80+x); // x position
+void GraphicOLED::g_write(uint8_t pat, int x, int y) {
+    writeCommand(0x80 + (x&0x7f)); // x position
+    writeCommand(0x40 + (y&0x01)); //y position
     writeData(pat);
 }
 
-void GraphicOLED::g_write(uint8_t *buf, int len, int x, int y)
-{
-    writeCommand(0x40+y); // y position
-    while(len-- > 0) {
-        writeCommand(0x80 + x++); // x position
-        writeData(*buf++);
+void GraphicOLED::g_write(uint8_t *buf, int len, int x, int y) {
+    for(int i = 0; i < len; i++) {
+        g_write(*buf++, x++, y);
     }
 }
 
@@ -74,15 +56,14 @@
     _e = 1;
 }
 
-void GraphicOLED::cls()
-{
-    for(int y = 0; y < 2; y++) {
+void GraphicOLED::cls() {
+    for(int y = 0; y < rows(); y++) {
         for(int x = 0; x < 100; x++) {
             g_write(0x00, x, y);
         }
     }
     locate(0,0);
-    _kanji_flag = false;
+    _uni_len = 0;
 }
 
 void GraphicOLED::locate(int column, int row) {
@@ -90,7 +71,9 @@
     _row = row;
 }
 
-int GraphicOLED::columns() { return 25; }
+int GraphicOLED::columns() {
+     return 25;
+}
 
 int GraphicOLED::rows() {
     return 2;
@@ -98,37 +81,48 @@
 
 int GraphicOLED::_putc(int value)
 {
+    int step = 0;
     if (value == '\n') {
         _column = 0;
         _row++;
         if (_row >= rows()) {
             _row = 0;
         }
-        _kanji_flag = false;
-    } else if (_kanji_flag) {
-        character2(_column, _row, _kanji_1st<<8 | value);
-        _kanji_flag = false;
-        _column += 2;
+        _uni_len = 0;
+    } else if (value <= 0x7f) {
+        step = character(_column, _row, value);
+    } else if (value >= 0xc2 && value <= 0xdf) {
+        _unicode = value & 0x1f;
+        _uni_len = 1;
+    } else if (value >= 0xe0 && value <= 0xef) {
+        _unicode = value & 0x0f;
+        _uni_len = 2;
+    } else if (value >= 0xf0 && value <= 0xf7) {
+        _unicode = value & 0x07;
+        _uni_len = 3;
+    } else if (value >= 0xf8 && value <= 0xfb) {
+        _unicode = value & 0x03;
+        _uni_len = 4;
+    } else if (value >= 0xfc && value <= 0xfd) {
+        _unicode = value & 0x01;
+        _uni_len = 5;
+    } else if (_uni_len >= 1 && value >= 0x80 && value <= 0xbf) {
+        _unicode = (_unicode<<6) | (value&0x3f);
+        if (--_uni_len == 0) {
+            step = character(_column, _row, _unicode);
+        }
+    } else {
+        _uni_len = 0;
+    }
+    if (step > 0) {
+        _column += step;
         if (_column >= columns()) {
             _column = 0;
-            _row++;
-            if (_row >= rows()) {
+            if (++_row >= rows()) {
                 _row = 0;
             }
         }
-    } else if (iskanji(value)) {
-        _kanji_1st = value;
-        _kanji_flag = true;
-    } else {
-        character(_column, _row, value);
-        _column++;
-        if (_column >= columns()) {
-            _column = 0;
-            _row++;
-            if (_row >= rows()) {
-                _row = 0;
-            }
-        }
+        _uni_len = 0;
     }
     return value;
 }
@@ -137,61 +131,23 @@
     return -1;
 }
 
-void GraphicOLED::character(int column, int row, int c)
-{
-    int i = 0;
-    if (c >= 0xa1 && c <= 0xdf) {
-        i = c - 66;
-    } else if (isprint(c)) { // 20 - 7e
-        i = c - 32;
+int GraphicOLED::character(int column, int row, int c) {
+    if (c <= 0x7f) { // 半角
+        uint8_t buf[4];
+        font_4x8(buf, c);
+        g_write(buf, sizeof(buf), column*4, row);
+        return 1;
+    } else if (c >= 0xff61 && c <= 0xff9f) { // 半角カタカナ
+        int i = c - 0xff61 + 0xa1;
+        uint8_t buf[4];
+        font_4x8(buf, i);
+        g_write(buf, sizeof(buf), column*4, row);
+        return 1;
+    } else { // 全角
+        uint8_t buf[8];
+        font_8x8(buf, c);
+        g_write(buf, sizeof(buf), column*4, row);
+        return 2;
     }
-    uint8_t buf[4];
-    font_4x8(buf, i);
-    g_write(buf, sizeof(buf), column*4, row);
-}
-
-void _jis(int *ph, int *pl)
-{
-    if (*ph <= 0x9F) {
-        if (*pl < 0x9F)  *ph = (*ph << 1) - 0xE1;
-        else             *ph = (*ph << 1) - 0xE0;
-    } else {
-        if (*pl < 0x9F)  *ph = (*ph << 1) - 0x161;
-        else             *ph = (*ph << 1) - 0x160;
-    }
-    if      (*pl < 0x7F) *pl -= 0x1F;
-    else if (*pl < 0x9F) *pl -= 0x20;
-    else                 *pl -= 0x7E;
 }
 
-int _jis2adrs(int jiscode)
-{
-    const int offset_table[][2] ={
-    {0x2121, 0}, {0x223a, 11}, {0x224a, 19}, {0x225c, 30}, {0x2272, 37}, {0x227e, 41}, {0x2330, 56},
-    {0x2341, 63}, {0x2361, 69}, {0x2421, 73}, {0x2521, 84}, {0x2621, 92}, {0x2641, 100}, {0x2721, 138},
-    {0x2751, 153}, {0x2821, 166}, {0x2d21, 604}, {0x2d40, 605}, {0x2d5f, 613}, {0x3021, 803},
-    {0x5021, 846}, {0x7ffff, 846}};
-    int ku = jiscode>>8;
-    int ten = jiscode&0xff; 
-    int adrs = (ku-0x21) * (0x7e-0x21+1);
-    adrs += (ten-0x21);
-    for(int i = 0; ; i++) { // adjust
-        if (jiscode >= offset_table[i][0] && jiscode < offset_table[i+1][0]) {
-            adrs -= offset_table[i][1];
-            break;
-        }
-    }
-    return adrs;
-}
-
-void GraphicOLED::character2(int column, int row, int c)
-{
-    int h,l;
-    h = c >> 8;
-    l = c & 0xff;
-    _jis(&h, &l);
-    int adrs = _jis2adrs(h<<8 | l);
-    uint8_t buf[8];
-    font_8x8(buf, adrs);
-    g_write(buf, sizeof(buf), column*4, row);
-}