asdasdasd

Dependencies:   mbed

Fork of FINAL_PROJECT_4180 by Gedeon Nyengele

cryst_lcd.cpp

Committer:
xemnas214
Date:
2016-11-23
Revision:
14:ca57ad53761b
Parent:
12:5cb9ffad1ad7

File content as of revision 14:ca57ad53761b:

/**
 * Driver for LCD devices based on the HD44780 controller
 */

/* Description

LCD SIZES SUPPORTED:
1-line displays: 8x1, 16x1, 20x1, 24x1, 32x1, 40x1
2-line displays: 16x2, 20x2, 24x2, 32x2, 40x2
4-line displays: 16x4, 20x4, 40x4

SUPPORTED PLATFORM: mbed
*/


#include "cryst_lcd.h"

Cryst_LCD::Cryst_LCD(PinName rs, PinName en, PinName db4, PinName db5,
                     PinName db6, PinName db7, LCDSize size)
    : _rs(rs), _en(en), _data(db4, db5, db6, db7)
{
    _size = size;
    _row = 0;
    _col = 0;
    _displayStatus = 0x0C;
    init();
}


void Cryst_LCD::cls()
{
    writeCommand(0x01, false);
    wait_ms(2);
    locate(0, 0);
}

void Cryst_LCD::locate(int row, int col)
{
    _row = 0;
    _col = col;

    if (row < getMaxRows()) {
        _row = row;
    }

    if (_col >= getMaxCols()) {
        _col = 0;
        if (_row < getMaxRows() - 1)
            _row++;
        else _row = 0;
    }

    int addr = getAddress(_row, _col);
    addr |= 0x80;
    writeCommand(addr);
}

void Cryst_LCD::display_off() { 
    _displayStatus &= 0x0B;
    writeCommand(_displayStatus);
}

void Cryst_LCD::display_on() {
    _displayStatus |= 0x04;
    writeCommand(_displayStatus);
}

void Cryst_LCD::cursor_on() {
    _displayStatus |= 0x02;
    writeCommand(_displayStatus);
}

void Cryst_LCD::cursor_off() {
    _displayStatus &= 0x0D;
    writeCommand(_displayStatus);
}

void Cryst_LCD::cursor_blink() {
    _displayStatus |= 0x01;
    writeCommand(_displayStatus);
}

void Cryst_LCD::cursor_no_blink() {
    _displayStatus &= 0x0E;
    writeCommand(_displayStatus);
}

void Cryst_LCD::clear_line() {
    int lineWidth = getMaxCols();

    for (int i = 0; i < lineWidth - 1; i++) {
        locate(_row, i);
        printf(" ");
    }

    locate(_row, 0);
}

void Cryst_LCD::reset()
{
    _rs = 0;
    wait_ms(15);     // wait approximately 15 ms
    writeNibble(0x3);  // write config data
    wait_ms(5);     // wait approximately 4.1 ms
    writeNibble(0x3);  // write config data again
    wait_us(100);  // wait approximately 100 us
}

void Cryst_LCD::init()
{
    reset();

    // Function set
    if (getMaxRows() <= 1) {   // 1-line display
        // (DF = 0, N = 0, F = 0)
        // 4-bit mode, 1-line display, 5x8 font size
        writeCommand(0x20);
    } else {  // Multi-line display
        // (DF = 0, N = 1, F = 0)
        // 4-bit mode, 2-line display, 5x8 font size
        writeCommand(0x28);
    }    

    // Entry Mode
    // (I/D = 1, S = 0)
    // DDRAM autoincrement, No display shifts
    writeCommand(0x06);

    // Display Control
    // (D = 1, C = 0, B = 0)
    // Display ON, cursor OFF, No cursor blinking
    writeCommand(_displayStatus);

    // Clear Display
    cls();
}

int Cryst_LCD::getAddress(int row, int col)
{
    int rowStartAddr[4] = {0x00, 0x40, 0x14, 0x54};
    int tempRow = 0, tempCol = 0;
    if (row < getMaxRows()) tempRow = row;
    if (col < getMaxCols()) tempCol = col;
    return rowStartAddr[tempRow] + tempCol;
}

// Default wait time is 40 us
void Cryst_LCD::writeData(int ch, bool use_default_timing)
{
    _rs = 1;
    writeNibble((ch >> 4) & 0x0F);
    writeNibble(ch & 0x0F);

    if (use_default_timing)
        wait_us(40);
}

// Default wait time is 40 us
void Cryst_LCD::writeCommand(int cmd, bool use_default_timing)
{
    _rs = 0;
    writeNibble((cmd >> 4) & 0x0F);
    writeNibble(cmd & 0x0F);

    if (use_default_timing)
        wait_us(40);
}

void Cryst_LCD::writeNibble(int nib)
{
    _data = nib & 0xF;
    wait_us(1);
    _en = 1;
    wait_us(1);
    _en = 0;
    wait_us(1);
}

void Cryst_LCD::getMaxDimensions(int* rowCount, int* colCount) {
    switch(_size) {
        // 1-line displays
        case LCD8x1:  *rowCount = 1; *colCount = 8;  break;
        case LCD16x1: *rowCount = 1; *colCount = 16; break;
        case LCD20x1: *rowCount = 1; *colCount = 20; break;
        case LCD24x1: *rowCount = 1; *colCount = 24; break;
        case LCD32x1: *rowCount = 1; *colCount = 32; break;
        case LCD40x1: *rowCount = 1; *colCount = 40; break;

        // 2-line displays
        case LCD16x2: *rowCount = 2; *colCount = 16; break;
        case LCD20x2: *rowCount = 2; *colCount = 20; break;
        case LCD24x2: *rowCount = 2; *colCount = 24; break;
        case LCD32x2: *rowCount = 2; *colCount = 32; break;
        case LCD40x2: *rowCount = 2; *colCount = 40; break;

        // 4-line displays
        case LCD16x4: *rowCount = 4; *colCount = 16; break;
        case LCD20x4: *rowCount = 4; *colCount = 20; break;
        case LCD40x4: *rowCount = 4; *colCount = 40; break;

        default: *rowCount = 0; *colCount = 0; break;
    }
}

int Cryst_LCD::getMaxRows()
{
    int rowCount = 0;
    int colCount = 0;
    getMaxDimensions(&rowCount, &colCount);
    return rowCount;
}

int Cryst_LCD::getMaxCols()
{
    int rowCount = 0;
    int colCount = 0;
    getMaxDimensions(&rowCount, &colCount);
    return colCount;
}

int Cryst_LCD::_putc(int ch)
{
    if (ch == '\n') {
        locate(_row + 1, 0);        
    }
        
    else if (ch == '\t') {      
        locate(_row, _col + 3);
    } 

    else if (ch == '\r') {  
        locate(_row, 0);
    }  

    else {
        locate(_row, _col);
        writeData(ch);
        locate(_row, _col + 1);
    }

    return ch;
}

int Cryst_LCD::_getc()
{
    return -5;
}