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; }