LCD module Switch Science SKU#1405, which driver IC is ST7032i.

st7032i.cpp

Committer:
coisme
Date:
2017-07-01
Revision:
0:92bfc61fb13b

File content as of revision 0:92bfc61fb13b:

#include "st7032i.h"

#define SLAVE_ADDR  0x3e

#define MAX_VAL_CONTRAST  63

#define CONTINUE     0x80
#define INSTRUCTION  0x00
#define NOT_CONTINUE 0x00
#define DATA         0x40

#define MAX_VAL_COLUMN    8
#define MAX_VAL_ROW       2

St7032i::St7032i(I2C *obj){
    i2c = obj;
}

St7032i::Status St7032i::init(){
    // Initialization command sequence. Check the data sheet.
    const char initSequence[] = {
            0x38,    // Function set
            0x39,    // Function set
            0x14,    // Internal OSC frequency
            0x70,    // Contrast set
            0x56,    // Power/ICON/Contrast control
            0x6c,    // Follower control
            0x38,    // Function set
            0x0c,    // Display ON/OFF control
            0x01     // Clear Display
        };
        
    // wait time after a command sent. Check the data sheet.
    const int t_wait_us[] = { 
            27, 27, 27, 27, 27, 200000, 27, 27, 1080  // micro-seconds
        };

    /* Somehow this workaround was needed on my test environment (BLENano) to 
     * make the module work correctly. Maybe the following issue is related to
     * this problem.
     * https://strawberry-linux.com/pub/i2c_lcd-an004.pdf
     */
    {
        i2c->start();    // start condition
        wait_us(100);
        i2c->stop();     // stop condition
        wait_us(100);
    }

    // number of commands
    int n_cmd = sizeof(initSequence)/sizeof(char);    

    // Execute the initialization sequence.
    for(int i=0; i < n_cmd; i++){
        char data[2] = {(INSTRUCTION | NOT_CONTINUE), initSequence[i]};
        if(i2c->write((SLAVE_ADDR << 1), data, 2) != 0){
            return ERROR_I2C_NO_ACK;
        }
        wait_us(t_wait_us[i]);
    }
    
    return SUCCESS;    
}

St7032i::Status St7032i::setContrast(uint8_t val){
    const int t_wait_us = 27;   // wait time in micro-seconds
    
    // sanity check
    if(MAX_VAL_CONTRAST < val){
        return INPUT_OUT_OF_RANGE;
    }
    
    char high = (0x54 | ((val & 0x30) >> 4));
    char low = (0x70 | (val & 0x0F));

    char sequence[] = {0x39, high, low, 0x38};    
    
    // Execute the command sequence
    int n = sizeof(sequence)/sizeof(char);
    for(int i=0; i < n; i++){
        char data[2] = {(INSTRUCTION | NOT_CONTINUE), sequence[i]};
        if(i2c->write((SLAVE_ADDR << 1), data, 2) != 0){
            return ERROR_I2C_NO_ACK;
        }
        wait_us(t_wait_us);
    }
    
    return SUCCESS;
}

St7032i::Status St7032i::setCursorPosition(uint8_t col, uint8_t row){
    // sanity check
    if( col > MAX_VAL_COLUMN || row > MAX_VAL_ROW){
        return INPUT_OUT_OF_RANGE;
    }
    
    char ddramAddr = (0x80 | (((row & 0x01) << 6) | (col & 0x0f)));
    
    char data[2] = {0x00, ddramAddr};
    if(i2c->write((SLAVE_ADDR << 1), data, 2) != 0){
        return ERROR_I2C_NO_ACK;
    }
    
    return SUCCESS;
}

St7032i::Status St7032i::putc(char c){
    char data[2] = {(NOT_CONTINUE | DATA), c};
    if(i2c->write((SLAVE_ADDR << 1), data, 2) != 0){
        return ERROR_I2C_NO_ACK;
    }
    return SUCCESS;
}


St7032i::Status St7032i::clear(bool wait){
    const int TIME_WAIT = 1080; // in micro-seconds
    char data[2] = {(NOT_CONTINUE | INSTRUCTION), 0x01};
    if(i2c->write((SLAVE_ADDR << 1), data, 2) != 0){
        return ERROR_I2C_NO_ACK;
    }
    if(wait){
        wait_us(TIME_WAIT);
    }
    return SUCCESS;
}

St7032i::Status St7032i::puts(const char *str, bool wrap){
    Status st;
    if((st=setCursorPosition(0,0)) != SUCCESS){
        return st;
    }
    for(int i=0; i < MAX_VAL_ROW; i++){
        for(int j=0; j < MAX_VAL_COLUMN; j++){
            char c = str[i*MAX_VAL_COLUMN+j];
            if(c == '\0'){
                return SUCCESS;
            }
            putc(c);
        }
        if(wrap){
            if((st=setCursorPosition(0,1)) != SUCCESS){
                return st;
            }
        }
    }          
    return SUCCESS;
}