PCF2119 library for I/O board

Fork of PCF2119 by Suga koubou

PCF2119.cpp

Committer:
okini3939
Date:
2014-07-09
Revision:
9:27f430d086f3
Parent:
TextLCD.cpp@ 7:44f34c09bd37

File content as of revision 9:27f430d086f3:

/* PCF2119x based I2C LCD Library
 * Copyright (c) 2014, Hiroshi Suga
 */
/* mbed TextLCD Library, for a 4-bit LCD based on HD44780
 * Copyright (c) 2007-2010, sford, http://mbed.org
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "PCF2119.h"
#include "mbed.h"

PCF2119::PCF2119(PinName sda, PinName sck, PinName reset, LCDType type, char addr) :
        _i2c(sda, sck), _reset(reset), _type(type), _addr(addr) {
    init();
}

PCF2119::PCF2119(I2C &i2c, PinName reset, LCDType type, char addr) :
        _i2c(i2c), _reset(reset), _type(type), _addr(addr) {
    init();
}

void PCF2119::init() {
    unsigned char buf[12];

    _reset = 1;
    wait(0.001);
    _reset = 0;
    wait(0.015);        // Wait 15ms to ensure powered up

    raw = 0;
    buf[0]  = 0x00; // CO=0, RS=0
    buf[1]  = 0x34; // Function_set     DL=1, M=1, SL=0, (H=0)
    buf[2]  = 0x0c; // Display_ctl      D=1, C=1, B=0
    buf[3]  = 0x06; // Entry_mode_set   ID=1, S=0
    buf[4]  = 0x35; // Function_set     DL=1, M=1, SL=0, (H=1)
    buf[5]  = 0x04; // Disp_conf        P=0, Q=0
    buf[6]  = 0x10; // Temp_ctl         TC1=0, TC2=0
    buf[7]  = 0x42; // HV_gen           S1=1, S2=0
    buf[8]  = 0x9f; // VLCD_set         V=0, VA=1f
    buf[9]  = 0x34; // Function_set     DL=1, M=1, SL=0, (H=0)
    buf[10] = 0x80; // set DDRAM
    buf[11] = 0x02; // Screen_conf      L=0
    _i2c.write(_addr, (char*)buf, 12);
    cls();
}

void PCF2119::character(int column, int row, int c) {
    unsigned char buf[2];
    buf[0] = 0x00; // CO=0, RS=0
    buf[1] = address(column, row);
    _i2c.write(_addr, (char*)buf, 2);
    writeData(c);
}

void PCF2119::cls() {
    char buf[2];
    buf[0] = 0x00; // CO=0, RS=0
    buf[1] = 0x01;
    _i2c.write(_addr, buf, 2);
    locate(0, 0);
}

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

int PCF2119::_putc(int value) {
    if (value == '\n') {
        _column = 0;
        _row++;
        if (_row >= rows()) {
            _row = 0;
        }
    } else {
        character(_column, _row, ascii2lcd(value));
        _column++;
        if (_column >= columns()) {
            _column = 0;
            _row++;
            if (_row >= rows()) {
                _row = 0;
            }
        }
    }
    return value;
}

int PCF2119::_getc() {
    return -1;
}

void PCF2119::writeCommand(int command) {
    unsigned char buf[2];
    buf[0] = 0x00; // CO=0, RS=0
    buf[1] = command;
    _i2c.write(_addr, (char*)buf, 2);
}

void PCF2119::writeData(int data) {
    unsigned char buf[2];
    buf[0] = 0x40; // CO=0, RS=1
    buf[1] = data;
    _i2c.write(_addr, (char*)buf, 2);
}

int PCF2119::address(int column, int row) {
    switch (_type) {
        case LCD20x4:
            switch (row) {
                case 0:
                    return 0x80 + column;
                case 1:
                    return 0xc0 + column;
                case 2:
                    return 0x94 + column;
                case 3:
                    return 0xd4 + column;
            }
        case LCD16x2B:
            return 0x80 + (row * 40) + column;
        case LCD16x2:
        case LCD20x2:
        default:
            return 0x80 + (row * 0x40) + column;
    }
}

int PCF2119::columns() {
    switch (_type) {
        case LCD20x4:
        case LCD20x2:
            return 20;
        case LCD16x2:
        case LCD16x2B:
        default:
            return 16;
    }
}

int PCF2119::rows() {
    switch (_type) {
        case LCD20x4:
            return 4;
        case LCD16x2:
        case LCD16x2B:
        case LCD20x2:
        default:
            return 2;
    }
}

int PCF2119::ascii2lcd (int c) {
    if (raw) return c;
    if (((c >= ' ') && (c <= '?')) || ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) {
        c |= 0x80;
    } else
    if (c >= 0xf0 && c <= 0xff) {
        c &= 0x0f;
    }
    return c;
}

void PCF2119::cgram(int num, const char *data, int len) {
    int i;
    unsigned char buf[1 + len];
    buf[0] = 0x00; // CO=0, RS=0
    buf[1] = 0x80 | (num >= 8 ? 0x40 : 0);
    _i2c.write(_addr, (char*)buf, 2);
    buf[0] = 0x00; // CO=0, RS=0
    buf[1] = 0x40 | (8 * (num % 8));
    _i2c.write(_addr, (char*)buf, 2);
    buf[0] = 0x40; // CO=0, RS=1
    for (i = 0; i < len; i ++) {
        buf[1 + i] = data[i];
    }
    _i2c.write(_addr, (char*)buf, 1 + len);
}