Text console library for ST7032 text LCD controller over I2C interface.

TextLCD_ST7032I2C.cpp

Committer:
kayekss
Date:
2015-04-06
Revision:
1:0b6f271981a5
Parent:
0:db0ffd858ca1

File content as of revision 1:0b6f271981a5:

// ==================================================== Mar 18 2015, kayeks ==
// TextLCD_ST7032I2C.cpp
// ===========================================================================
// Text console library for ST7032 text LCD controller over I2C interface.

#include <string.h>
#include "TextLCD_ST7032I2C.h"

TextLCD_ST7032I2C::TextLCD_ST7032I2C(PinName sda, PinName scl, uint8_t address,
                                     uint8_t columns, uint8_t rows)
:
    _i2c(sda, scl)
{
    // Copy parameters
    _columns = MIN(columns, 16);
    _rows = MIN(rows, 2);
    _address = address & 0xfe;
    
    // Allocate line buffer
    _lineBuffer = new uint8_t*[_rows];
    for (uint8_t i = 0; i < _rows; i++) {
        _lineBuffer[i] = new uint8_t[_columns];
    }
}

TextLCD_ST7032I2C::~TextLCD_ST7032I2C() {
    for (uint8_t i = 0; i < _rows; i++) {
        delete[] _lineBuffer[i];
    }
    delete[] _lineBuffer;
}

void TextLCD_ST7032I2C::clear() {
    for (uint8_t j = 0; j < _rows; j++) {
        locate(0, j);
        for (uint8_t i = 0; i < _columns; i++) {
            data(' ');
        }
    }
}

void TextLCD_ST7032I2C::init(uint8_t osc, uint8_t rab, uint8_t contrast, Bias bias) {
    // Copy parameters
    _osc = osc & 0x07;
    _rab = MIN(rab, 7);
    _contrast = MIN(contrast, 63);
    _bias = bias;
    
    command(FUNCTION_8B_2LINE_7DOT_IS0);
    command(FUNCTION_8B_2LINE_7DOT_IS1);
    switch (bias) {
    case Bias1_4:
        command(IS1_BIAS4_OSC + _osc);
        break;
    case Bias1_5:
        command(IS1_BIAS5_OSC + _osc);
        break;
    }
    command(IS1_CONTRAST + (_contrast & 0x0f));
    command(IS1_ICON_ON_BOOST_ON_CONTRAST + (_contrast >> 4));
    command(IS1_FOLLOWER_ON_RAB + _rab);
    if (_rows == 1) {
        command(FUNCTION_8B_1LINE_7DOT_IS0);
    } else if (_rows == 2) {
        command(FUNCTION_8B_2LINE_7DOT_IS0);
    }
    command(DISPLAY_ON_CURSOR_OFF_POS_OFF);
    cls();
}

void TextLCD_ST7032I2C::cls() {
    clear();
    for (uint8_t j = 0; j < _rows; j++) {
        memset(_lineBuffer[j], ' ', _columns);
    }
    _column = 0;
    _row = 0;
}

void TextLCD_ST7032I2C::locate(uint8_t column, uint8_t row) {
    if (column < _columns && row < _rows) {
        command(DDRAM + ((row << 6) | column));
        _column = column;
        _row = row;
    }
}

void TextLCD_ST7032I2C::iconOn() {
    is1();
    command(IS1_ICON_ON_BOOST_ON_CONTRAST + (_contrast >> 4));
}

void TextLCD_ST7032I2C::iconOff() {
    is1();
    command(IS1_ICON_OFF_BOOST_ON_CONTRAST + (_contrast >> 4));
}

void TextLCD_ST7032I2C::setIcon(uint8_t iconAddr, uint8_t bits) {
    is1();
    command(IS1_ICON_ADDR + (iconAddr & 0x0f));
    data(bits & 0x1f);
}

int TextLCD_ST7032I2C::_putc(int c) {
    switch (c) {
    case '\r':  // Carriage return
        _column = 0;
        locate(_column, _row);
        break;
    case '\n':  // Line feed
        if (_row == _rows - 1) {
            shiftUp();
        } else {
            _row++;
        }
        break;
    case '\f':  // Form feed
        // Clear screen
        cls();
        break;
    default:
        // Break line if the cursor reaches end
        if (_column == _columns) {
            if (_row == _rows - 1) {
                shiftUp();
            } else {
                _row++;
            }
            _column = 0;
        }
        locate(_column, _row);
        data(c);
        _lineBuffer[_row][_column] = c;
        _column++;
        break;
    }
    return 0;
}

int TextLCD_ST7032I2C::_getc() {
    return 0;
}

void TextLCD_ST7032I2C::shiftUp() {
    // Move line buffer content
    for (uint8_t j = 0; j < _rows - 1; j++) {
        memcpy(_lineBuffer[j], _lineBuffer[j + 1], _columns);
    }
    // Clear last line
    memset(_lineBuffer[_rows - 1], ' ', _columns);
    
    // Redraw
    for (uint8_t j = 0; j < _rows; j++) {
        locate(0, j);
        for (uint8_t i = 0; i < _columns; i++) {
            data(_lineBuffer[j][i]);
        }
    }
}

void TextLCD_ST7032I2C::is0() {
    if (_rows == 1) {
        command(FUNCTION_8B_1LINE_7DOT_IS0);
    } else if (_rows == 2) {
        command(FUNCTION_8B_2LINE_7DOT_IS0);
    }
}

void TextLCD_ST7032I2C::is1() {
    if (_rows == 1) {
        command(FUNCTION_8B_1LINE_7DOT_IS1);
    } else if (_rows == 2) {
        command(FUNCTION_8B_2LINE_7DOT_IS1);
    }
}

void TextLCD_ST7032I2C::command(uint8_t c) {
    char cbuf[2];
    
    cbuf[0] = 0x00;
    cbuf[1] = c;
    _i2c.write(_address, cbuf, 2);
}

void TextLCD_ST7032I2C::data(uint8_t d) {
    char dbuf[2];
    
    dbuf[0] = 0x40;
    dbuf[1] = d;
    _i2c.write(_address, dbuf, 2);
}