NokiaLCDに美咲フォントを組み込んで日本語出力ができるようにしたものです。 NOKIA330用の設定と\"\\n\"による改行も追加されています。

NokiaLCD.cpp

Committer:
nucho
Date:
2010-10-19
Revision:
0:839ab88da656

File content as of revision 0:839ab88da656:

/* mbed Nokia LCD Library
 * Copyright (c) 2007-2010, sford
 */

#include "NokiaLCD.h"
#include "small_font.h"
#include "mbed.h"

#define NOKIALCD_ROWS 16
#define NOKIALCD_COLS 16
#define NOKIALCD_WIDTH 130
#define NOKIALCD_HEIGHT 130
#define NOKIALCD_FREQUENCY 5000000

#define countof(x) ( sizeof(x) / sizeof(x[0]) )

bool kstate = false;
unsigned int kbuf;

NokiaLCD::NokiaLCD(PinName mosi, PinName sclk, PinName cs, PinName rst, LCDType type)
        : _spi(mosi, NC, sclk)
        , _rst(rst)
        , _cs(cs) {

    _type = type;

    _row = 0;
    _column = 0;
    _foreground = 0x00FFFFFF;
    _background = 0x00000000;

    reset();
}

void NokiaLCD::reset() {

    // setup the SPI interface and bring display out of reset
    _cs = 1;
    _rst = 0;
    _spi.format(9);
    _spi.frequency(NOKIALCD_FREQUENCY);
    wait_ms(1);
    _rst = 1;
    wait_ms(1);

    _cs = 0;

    switch (_type) {
        case LCD6100:
            command(0xCA); // display control
            data(0);
            data(32);
            data(0);
            command(0xBB);
            data(1);
            command(0xD1); // oscillator on
            command(0x94); // sleep out
            command(0x20); // power control
            data(0x0F);
            command(0xA7); // invert display
            command(0x81); // Voltage control
            data(39);      // contrast setting: 0..63
            data(3);       // resistance ratio
            wait_ms(1);
            command(0xBC);
            data(0);
            data(1);
            data(4);
            command(0xAF);  // turn on the display
            break;

        case LCD6610:
            command(0xCA);    // display control
            data(0);
            data(31);
            data(0);
            command(0xBB);
            data(1);
            command(0xD1); // oscillator on
            command(0x94); // sleep out
            command(0x20); // power control
            data(0x0F);
            command(0xA7); // invert display
            command(0x81); // Voltage control
            data(39);      // contrast setting: 0..63
            data(3);       // resistance ratio
            wait_ms(1);
            command(0xBC);
            data(0);
            data(0);
            data(2);
            command(0xAF);  // turn on the display
            break;

        case LCD3300:
            command(0xCA); // display control
            data(0);
            data(32);
            data(0);
            command(0xBB);
            data(1);
            command(0xD1); // oscillator on
            command(0x94); // sleep out
            command(0x20); // power control
            data(0x0F);
            command(0xA7); // invert display
            command(0x81); // Voltage control
            data(39);      // contrast setting: 0..63
            data(3);       // resistance ratio
            wait_ms(1);
            command(0xBC);
            data(1);
            data(0);
            data(4);
            command(0xAF);  // turn on the display
            break;

        case PCF8833:
            command(0x11);  // sleep out
            command(0x3A);  // column mode
            data(0x05);
            command(0x36);  // madctl
            data(0x60);     // vertical RAM, flip x
            command(0x25);  // setcon
            data(0x30);// contrast 0x30
            wait_ms(2);
            command(0x29);//DISPON
            command(0x03);//BSTRON
            break;
    }

    _cs = 1;

    cls();
}

void NokiaLCD::command(int value) {
    _spi.write(value & 0xFF);
}

void NokiaLCD::data(int value) {
    _spi.write(value | 0x100);
}

void NokiaLCD::_window(int x, int y, int width, int height) {
    int x1 = x + 2;
    int y1 = y + 0;
    int x2 = x1 + width - 1;
    int y2 = y1 + height - 1;

    switch (_type) {
        case LCD6100:
        case LCD6610:
        case LCD3300:
            command(0x15); // column
            data(x1);
            data(x2);
            command(0x75); // row
            data(y1);
            data(y2);
            command(0x5C); // start write to ram
            break;
        case PCF8833:
            command(0x2A);  // column
            data(x1);
            data(x2);
            command(0x2B); // row
            data(y1);
            data(y2);
            command(0x2C); // start write to ram
            break;
    }
}

void NokiaLCD::_putp(int colour) {
    int gr = ((colour >> 20) & 0x0F)
             | ((colour >> 8 ) & 0xF0);
    int nb = ((colour >> 4 ) & 0x0F);
    data(nb);
    data(gr);
}


void NokiaLCD::locate(int column, int row) {
    _column = column;
    _row = row;
}

void NokiaLCD::newline() {
    _column = 0;
    _row++;
    if (_row >= NOKIALCD_ROWS) {
        _row = 0;
    }
}

unsigned int NokiaLCD::findface(unsigned short c) {
    unsigned int p = 0;
    int i, sum;
    for (sum = i = 0; i < countof(font8table); i++) {
        if (font8table[i].start <= c && c <= font8table[i].end) {
            p = (sum + c - font8table[i].start);
            break;
        }
        sum += font8table[i].end - font8table[i].start + 1;
    }
    return p;
}

int NokiaLCD::_putc(int value) {
    int x = _column * 8;  // FIXME: Char sizes
    int y = _row * 8;

    if(value == '\n') {
        newline();
    } else if (kstate) { // 2nd byte of shift-jis
        kstate = false;
        int p = findface(kbuf << 8 | value);
        bitblit(x + 1, y + 1, 8,8, (char*)&(FontLookup[p][0]));

           //printf("%x %x",( kbuf << 8 | value),p); //for debug
        _column++;
        if (_column >= NOKIALCD_COLS) {
            _row++;
            _column = 0;
        }
        if (_row >= NOKIALCD_ROWS) {
            _row = 0;
        }
    } else if ((0x81 <= value && value <= 0x9f) || (0xe0 <= value && value <= 0xfc)) { // 1st byte of shift-jis
        kstate = true;
        kbuf = value;
    } else {
        bitblit(x + 1, y + 1, 8, 8, (char*)&(FontLookup_ABC[value-32][0]));
        _column++;
        if (_column >= NOKIALCD_COLS) {
            _row++;
            _column = 0;
        }
        if (_row >= NOKIALCD_ROWS) {
            _row = 0;
        }
    }

    return value;
}

void NokiaLCD::cls() {
    fill(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT, _background);
    _row = 0;
    _column = 0;
}


void NokiaLCD::window(int x, int y, int width, int height) {
    _cs = 0;
    _window(x, y, width, height);
    _cs = 1;
}

void NokiaLCD::putp(int colour) {
    _cs = 0;
    _putp(colour);
    _cs = 1;
}

void NokiaLCD::pixel(int x, int y, int colour) {
    _cs = 0;
    _window(x, y, 1, 1);
    _putp(colour);
    _cs = 1;
}

void NokiaLCD::fill(int x, int y, int width, int height, int colour) {
    _cs = 0;
    _window(x, y, width, height);
    for (int i=0; i<width*height; i++) {
        _putp(colour);
    }
    _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
    _cs = 1;
}

void NokiaLCD::blit(int x, int y, int width, int height, const int* colour) {
    _cs = 0;
    _window(x, y, width, height);
    for (int i=0; i<width*height; i++) {
        _putp(colour[i]);
    }
    _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
    _cs = 1;
}

void NokiaLCD::bitblit(int x, int y, int width, int height, const char* bitstream) {
    _cs = 0;
    _window(x, y, width, height);
    for (int i=0; i<height*width; i++) {
        int byte = i / 8;
        int bit = i % 8;
        int colour = ((bitstream[byte] << bit) & 0x80) ? _foreground : _background;
        _putp(colour);
    }
    _window(0, 0, _width, _height);
    _cs = 1;
}




void NokiaLCD::foreground(int c) {
    _foreground = c;
}

void NokiaLCD::background(int c) {
    _background = c;
}

int NokiaLCD::width() {
    return NOKIALCD_WIDTH;
}

int NokiaLCD::height() {
    return NOKIALCD_HEIGHT;
}

int NokiaLCD::columns() {
    return NOKIALCD_COLS;
}

int NokiaLCD::rows() {
    return NOKIALCD_ROWS;
}