Graphic OLED 100x16 pixels interface

Dependents:   mbed_nicovideo_search_api mbed_recent_nicovideo_display_pub

/media/uploads/va009039/graphicoled_1.jpg

GraphicOLED.cpp

Committer:
va009039
Date:
2012-04-18
Revision:
1:a104653979bf
Parent:
0:67d983a1ed3e
Child:
2:337a2655f815

File content as of revision 1:a104653979bf:

// GraphicOLED.cpp
#include "GraphicOLED.h"
#include <ctype.h>

extern void font_4x8(char buf[], int i);
extern void font_8x8(char buf[], int i);

GraphicOLED::GraphicOLED(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7):
        TextLCD(rs, e, d4, d5, d6, d7)
{
    wait_ms(500); // wait 500ms
    writeCommand(0x00); // 0x0 x 5
    writeCommand(0x00);
    writeCommand(0x02); // function set
    writeCommand(0x28); // N=1
    writeCommand(0x0c); // D=1 display on
    writeCommand(0x14); // S/C=0 R/L=1
    writeCommand(0x1f); // G/C=1 graphic mode
    _kanji_flag = false;
}

void GraphicOLED::g_wrtie(int pat, int x, int y)
{
    writeCommand(0x40+y); // y position
    writeCommand(0x80+x); // x position
    writeData(pat);
}

void GraphicOLED::g_wrtie(char *buf, int len, int x, int y)
{
    writeCommand(0x40+y); // y position
    while(len-- > 0) {
        writeCommand(0x80 + x++); // x position
        writeData(*buf++);
    }
}

void GraphicOLED::cls()
{
    for(int y = 0; y < 2; y++) {
        for(int x = 0; x < 100; x++) {
            g_wrtie(0x00, x, y);
        }
    }
    locate(0,0);
    _kanji_flag = false;
}

int GraphicOLED::columns() { return 25; }

int GraphicOLED::_putc(int value)
{
    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;
        if (_column >= columns()) {
            _column = 0;
            _row++;
            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;
            }
        }
    }
    return value;
}

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;
    }
    char buf[4];
    font_4x8(buf, i);
    g_wrtie(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);
    char buf[8];
    font_8x8(buf, adrs);
    g_wrtie(buf, sizeof(buf), column*4, row);
}