Initial version for Modtronix LCD2S I2C and SPI serial LCD displays. For details, see http://modtronix.com/products-serial-lcd-board/

lcd2s_i2c.cpp

Committer:
modtronix
Date:
2015-08-07
Revision:
2:fe0c1e27f362
Parent:
1:429b7d3f7b95

File content as of revision 2:fe0c1e27f362:

/**
 * File:      lcd2s_i2c.cpp
 *
 * Author:    Modtronix Engineering - www.modtronix.com
 *
 * Description:
 *
 * Software License Agreement:
 * This software has been written or modified by Modtronix Engineering. The code
 * may be modified and can be used free of charge for commercial and non commercial
 * applications. If this is modified software, any license conditions from original
 * software also apply. Any redistribution must include reference to 'Modtronix
 * Engineering' and web link(www.modtronix.com) in the file header.
 *
 * THIS SOFTWARE IS PROVIDED IN AN 'AS IS' CONDITION. NO WARRANTIES, WHETHER EXPRESS,
 * IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE
 * COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 */
#include "mbed.h"
#include "lcd2s_i2c.h"


// DEFINES ////////////////////////////////////////////////////////////////////


// GLOBAL VARIABLES ///////////////////////////////////////////////////////////


// Function Prototypes ////////////////////////////////////////////////////////


LCD2S_I2C::LCD2S_I2C(I2C* i2c, uint8_t rows/* = 4*/, uint8_t columns/* = 20*/)
        : LCD2S(rows, columns)
{
    pI2C = i2c;
    i2cAdr = 0x50;      //Default I2C address of the LCD
}

/** Initializes the LCD2S device with default values
 * - Interrupt pin is Open Collector output type
 * - Backlight On
 * - Display On
 * - Backlight 200 (value from 0 to 255)
 * - Cursor off, block cursor off
 * - Cursor moves forward
 * - Keypad is 4x4 button type (if present)
 * - OUT1 disabled
 * - GPIO1 to 3 disabled
 * - Keypad Buzzer off
 * - Keypad repeat rate = 320ms
 * - Keypad Repeat Delay = 1 second
 * - Keypad Debounce Time = 64ms
 *
 * @param contrast The display contrast, a value from 0 to 255
 */
void LCD2S_I2C::initDefault(uint8_t contrast) {
    char cmd[8];

    //Byte 1 = 0x95
    //Configure LCD using "Configure Device" command
    cmd[0] = LCD2S_CMD_CONFIG_DEVICE;

    //Byte 2 (Display) of command
    //xx1x xxxx - Interrupt pin is Open Collector output type
    //xxx1 1xxx - Backlight On, Display On
    //xxxx x001 - Cursor off, block cursor off, Cursor moves forward
    //0011 1001 = 0x39
    cmd[1] = 0x39;

    //Byte 3 (Contrast and Brightness) of command
    //01xx xxxx - Set Backlight to 100 (range is 0 to 255)
    //xx11 0111 - Set contrast to 220 (0x37 x 4)
    //0111 0111 = 0x77
    cmd[2] = 0x77;

    //Byte 4 (keypad and IO) of command
    //0x0f Configures device for 4x4 keypad (if present), OUT1 disabled, GPIO1 to 3 disabled
    cmd[3] = 0x0f;

    //Byte 5 (Keypad and Buzzer) of command
    //01xx xxxx - Keypad Buzzer off
    //xx10 xxxx - Keypad repeat rate = 320ms
    //xxxx 10xx - Keypad Repeat Delay = 1 second
    //xxxx xx10 - Keypad Debounce Time = 64ms
    //0110 1010 = 0x6A
    cmd[4] = 0x6a;

    pI2C->write(i2cAdr, cmd, 5);
}


/** Causes the display to be updated with buffer content
 */
uint8_t LCD2S_I2C::display(void) {
    uint8_t retVal = 0;
    uint8_t row, col;
    uint8_t colFirstDirty   = 0xff;
    uint8_t colLastDirty    = 0xff;
    uint32_t mask           = 0;
    char cmd[32];

//    bool changed = FALSE;
//
//    //Check if anything changed
//    for (row=0; row<rows; row++) {
//        if(pDirtyRows[row] != 0) {
//            changed = TRUE;
//            break;
//        }
//    }
//
//    if (changed == FALSE)
//        return;

    //Write to dirty rows
    for (row=0; row<rows; row++) {
        if(pDirtyRows[row] != 0) {
            mask = 0x01;
            //Get first and last dirty characters in current row
            for(col=0; col<columns; col++) {
                //Is current char dirty?
                if ((pDirtyRows[row] & mask) != 0) {
                    if(colFirstDirty == 0xff)
                        colFirstDirty = col;
                    colLastDirty=col;
                }
                mask = mask << 1;
            }

            //Set cursor position
            cmd[0] = LCD2S_CMD_SET_CURSOR_POSITION;
            cmd[1] = row+1;
            cmd[2] = colFirstDirty+1;
            if ((retVal = pI2C->write(this->i2cAdr, cmd, 3)) != 0) {
                return retVal;  //Return error code
            }
            wait_ms(5);

            //Write string - only dirty characters are written
            cmd[0] = LCD2S_CMD_WRITE_STRING;
            for(col=colFirstDirty; col<=colLastDirty; col++) {
                cmd[col-colFirstDirty+1] = pBuf[(row*columns)+col];
            }
            if ((retVal = pI2C->write(this->i2cAdr, cmd, colLastDirty-colFirstDirty+2)) != 0) {
                return retVal;  //Return error code
            }
        }
    }

    return retVal;
}

int LCD2S_I2C::writeChar(uint8_t c) {
    //Write to buffer
    pBuf[(cursor_row * columns) + cursor_col] = c;

    //Set dirty flag
    pDirtyRows[cursor_row] |= 0x01 << cursor_col;

    if (++cursor_col >= columns) {
        cursor_col = 0;

        if (++cursor_row >= rows) {
            cursor_row = 0;
        }
    }
    return 0;
}

//void LCD2S_I2C::write(const char* str) {
//    char cmd[32];
//
//    cmd[0] = LCD2S_CMD_WRITE_STRING;
//    cmd[1] = 0x0c;   //Clear display and go to first line
//    cmd[2] = 'H';
//    cmd[3] = 'o';
//    pI2C->write(this->i2cAdr, cmd, 4);
//}