Rod Coleman / I2CTextLCD
Committer:
RodColeman
Date:
Thu Aug 18 13:05:56 2011 +0000
Revision:
1:e60cbc407d73
Parent:
0:9d621b44ea24
Child:
2:24c878e63f10
no change of i2c freq

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RodColeman 0:9d621b44ea24 1 /* mbed I2CTextLCD Library
RodColeman 0:9d621b44ea24 2 * Copyright (c) 2007-2009 sford
RodColeman 0:9d621b44ea24 3 * Copyright (c) 2010 Wim De Roeve changed to work with I2C PCF8575
RodColeman 0:9d621b44ea24 4 * Released under the MIT License: http://mbed.org/license/mit
RodColeman 0:9d621b44ea24 5 */
RodColeman 0:9d621b44ea24 6
RodColeman 0:9d621b44ea24 7 #include "I2CTextLCD.h"
RodColeman 0:9d621b44ea24 8 #include "mbed.h"
RodColeman 0:9d621b44ea24 9 #include "error.h"
RodColeman 0:9d621b44ea24 10
RodColeman 0:9d621b44ea24 11 using namespace mbed;
RodColeman 0:9d621b44ea24 12
RodColeman 0:9d621b44ea24 13 /*
RodColeman 0:9d621b44ea24 14 * useful info found at http://www.a-netz.de/lcd.en.php
RodColeman 0:9d621b44ea24 15 *
RodColeman 0:9d621b44ea24 16 *
RodColeman 0:9d621b44ea24 17 * Initialisation
RodColeman 0:9d621b44ea24 18 * ==============
RodColeman 0:9d621b44ea24 19 *
RodColeman 0:9d621b44ea24 20 * After attaching the supply voltage/after a reset, the display needs to be brought in to a defined state
RodColeman 0:9d621b44ea24 21 *
RodColeman 0:9d621b44ea24 22 * - wait approximately 15 ms so the display is ready to execute commands
RodColeman 0:9d621b44ea24 23 * - Execute the command 0x30 ("Display Settings") three times (wait 1,64ms after each command, the busy flag cannot be queried now).
RodColeman 0:9d621b44ea24 24 * - The display is in 8 bit mode, so if you have only connected 4 data pins you should only transmit the higher nibble of each command.
RodColeman 0:9d621b44ea24 25 * - If you want to use the 4 bit mode, now you can execute the command to switch over to this mode now.
RodColeman 0:9d621b44ea24 26 * - Execute the "clear display" command
RodColeman 0:9d621b44ea24 27 *
RodColeman 0:9d621b44ea24 28 * Timing
RodColeman 0:9d621b44ea24 29 * ======
RodColeman 0:9d621b44ea24 30 *
RodColeman 0:9d621b44ea24 31 * Nearly all commands transmitted to the display need 40us for execution.
RodColeman 0:9d621b44ea24 32 * Exceptions are the commands "Clear Display and Reset" and "Set Cursor to Start Position"
RodColeman 0:9d621b44ea24 33 * These commands need 1.64ms for execution. These timings are valid for all displays working with an
RodColeman 0:9d621b44ea24 34 * internal clock of 250kHz. But I do not know any displays that use other frequencies. Any time you
RodColeman 0:9d621b44ea24 35 * can use the busy flag to test if the display is ready to accept the next command.
RodColeman 0:9d621b44ea24 36 *
RodColeman 0:9d621b44ea24 37 */
RodColeman 0:9d621b44ea24 38
RodColeman 0:9d621b44ea24 39 I2CTextLCD::I2CTextLCD(PinName sda, PinName scl, int i2cAddress , int columns, int rows,
RodColeman 0:9d621b44ea24 40 bool backlight) : _i2c(sda, scl) {
RodColeman 0:9d621b44ea24 41
RodColeman 0:9d621b44ea24 42 _i2cAddress = i2cAddress;
RodColeman 0:9d621b44ea24 43 _columns = columns;
RodColeman 0:9d621b44ea24 44 _rows = rows;
RodColeman 0:9d621b44ea24 45 _backlight=backlight;
RodColeman 1:e60cbc407d73 46 //_i2c.frequency(70000);
RodColeman 0:9d621b44ea24 47
RodColeman 0:9d621b44ea24 48
RodColeman 0:9d621b44ea24 49 // Should theoretically wait 15ms, but most things will be powered up pre-reset
RodColeman 0:9d621b44ea24 50 // so i'll disable that for the minute. If implemented, could wait 15ms post reset
RodColeman 0:9d621b44ea24 51 // instead
RodColeman 0:9d621b44ea24 52 // Winstar 20x4 WH2004-NYG- needs 40ms after VDD> 4,5V
RodColeman 0:9d621b44ea24 53 wait(0.05);
RodColeman 0:9d621b44ea24 54
RodColeman 0:9d621b44ea24 55 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
RodColeman 0:9d621b44ea24 56
RodColeman 0:9d621b44ea24 57 for (int i=0; i<3; i++) {
RodColeman 0:9d621b44ea24 58 writeCommand(0x3); //send 3 times mode
RodColeman 0:9d621b44ea24 59 wait(0.00164); // this command takes 1.64ms, so wait for it
RodColeman 0:9d621b44ea24 60 }
RodColeman 0:9d621b44ea24 61 writeCommand(0x2); // 4-bit mode
RodColeman 0:9d621b44ea24 62 writeCommand(0x2); // 4-bit mode
RodColeman 0:9d621b44ea24 63
RodColeman 0:9d621b44ea24 64 writeCommand(0x28); // Function set 001 BW N F - -
RodColeman 0:9d621b44ea24 65 wait(0.001);
RodColeman 0:9d621b44ea24 66 writeCommand(0x28); // Function set 001 BW N F
RodColeman 0:9d621b44ea24 67 wait(0.001);
RodColeman 0:9d621b44ea24 68 writeCommand(0x0C); // turns display ON, no cursor. Use 0x0E for cursor ON.
RodColeman 0:9d621b44ea24 69 /* 0x28 also works for Winstar WEH002004ALPP5N00000 OLED display. 0x29= westEuro fon table, 0x2A = UK/Russian
RodColeman 0:9d621b44ea24 70 */
RodColeman 0:9d621b44ea24 71 // Added RC 2011-8-11
RodColeman 0:9d621b44ea24 72 writeCommand(0x01); // clear display RAM all to 00
RodColeman 0:9d621b44ea24 73 wait(0.007); // 6.2ms specified for OLED display to recover from RAM clear
RodColeman 0:9d621b44ea24 74
RodColeman 0:9d621b44ea24 75 writeCommand(0x06); // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
RodColeman 0:9d621b44ea24 76
RodColeman 0:9d621b44ea24 77 cls();
RodColeman 0:9d621b44ea24 78
RodColeman 0:9d621b44ea24 79
RodColeman 0:9d621b44ea24 80 }
RodColeman 0:9d621b44ea24 81
RodColeman 0:9d621b44ea24 82 int I2CTextLCD::_putc(int value) {
RodColeman 0:9d621b44ea24 83 if (value == '\n') {
RodColeman 0:9d621b44ea24 84 newline();
RodColeman 0:9d621b44ea24 85 } else {
RodColeman 0:9d621b44ea24 86 writeData(value);
RodColeman 0:9d621b44ea24 87 }
RodColeman 0:9d621b44ea24 88 return value;
RodColeman 0:9d621b44ea24 89 }
RodColeman 0:9d621b44ea24 90
RodColeman 0:9d621b44ea24 91 int I2CTextLCD::_getc() {
RodColeman 0:9d621b44ea24 92 return 0;
RodColeman 0:9d621b44ea24 93 }
RodColeman 0:9d621b44ea24 94
RodColeman 0:9d621b44ea24 95 /* void I2CTextLCD::backlight(bool status) {
RodColeman 0:9d621b44ea24 96 _backlight=status;
RodColeman 0:9d621b44ea24 97 if (_backlight)
RodColeman 0:9d621b44ea24 98 writeI2CByte(BACKLIGHT_ON | E1_ON);
RodColeman 0:9d621b44ea24 99 else
RodColeman 0:9d621b44ea24 100 writeI2CByte(E1_ON);
RodColeman 0:9d621b44ea24 101 }
RodColeman 0:9d621b44ea24 102 */
RodColeman 0:9d621b44ea24 103
RodColeman 0:9d621b44ea24 104 void I2CTextLCD::newline() {
RodColeman 0:9d621b44ea24 105 _column = 0;
RodColeman 0:9d621b44ea24 106 _row++;
RodColeman 0:9d621b44ea24 107 if (_row >= _rows) {
RodColeman 0:9d621b44ea24 108 _row = 0;
RodColeman 0:9d621b44ea24 109 }
RodColeman 0:9d621b44ea24 110 locate(_column, _row);
RodColeman 0:9d621b44ea24 111 }
RodColeman 0:9d621b44ea24 112
RodColeman 0:9d621b44ea24 113 void I2CTextLCD::locate(int column, int row) {
RodColeman 0:9d621b44ea24 114 if (column < 0 || column >= _columns || row < 0 || row >= _rows) {
RodColeman 0:9d621b44ea24 115 error("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows);
RodColeman 0:9d621b44ea24 116 return;
RodColeman 0:9d621b44ea24 117 }
RodColeman 0:9d621b44ea24 118 _row = row;
RodColeman 0:9d621b44ea24 119 _column = column;
RodColeman 0:9d621b44ea24 120 int address;
RodColeman 0:9d621b44ea24 121 if (row==0){
RodColeman 0:9d621b44ea24 122 address = 0x80+_column;
RodColeman 0:9d621b44ea24 123 }
RodColeman 0:9d621b44ea24 124 else if (row==1){
RodColeman 0:9d621b44ea24 125 address= 0xc0+_column;
RodColeman 0:9d621b44ea24 126 }
RodColeman 0:9d621b44ea24 127 else if (row==2){
RodColeman 0:9d621b44ea24 128 address=0x94+_column;
RodColeman 0:9d621b44ea24 129 }
RodColeman 0:9d621b44ea24 130 else if(row==3){
RodColeman 0:9d621b44ea24 131 address=0xd4+_column;
RodColeman 0:9d621b44ea24 132 }
RodColeman 0:9d621b44ea24 133 /*
RodColeman 0:9d621b44ea24 134 int address = 0x80 + (_row * 40) + _column; // memory starts at 0x00, and is 40 chars long per row
RodColeman 0:9d621b44ea24 135 Set bit 7 also, to signify ADDRESS SET mode.
RodColeman 0:9d621b44ea24 136 // pc_LCD.traceOut("locate %dx%d\r\n", column, row);
RodColeman 0:9d621b44ea24 137 */
RodColeman 0:9d621b44ea24 138 writeCommand(address); // must set bit 7 to indicate address SET command
RodColeman 0:9d621b44ea24 139 wait(0.004); // takes 1.5ms on Winstar LCD 20x4
RodColeman 0:9d621b44ea24 140 }
RodColeman 0:9d621b44ea24 141
RodColeman 0:9d621b44ea24 142 void I2CTextLCD::cls() {
RodColeman 0:9d621b44ea24 143 writeCommand(0x01); // Clear Display
RodColeman 0:9d621b44ea24 144 wait(0.007f); // This command takes 1.64 ms (LCD), 6.2ms for Winstar OLED
RodColeman 0:9d621b44ea24 145 locate(0, 0);
RodColeman 0:9d621b44ea24 146 }
RodColeman 0:9d621b44ea24 147
RodColeman 0:9d621b44ea24 148 void I2CTextLCD::reset() {
RodColeman 0:9d621b44ea24 149 cls();
RodColeman 0:9d621b44ea24 150 }
RodColeman 0:9d621b44ea24 151
RodColeman 0:9d621b44ea24 152 void I2CTextLCD::writeByte(int c, bool rs) {
RodColeman 0:9d621b44ea24 153 // void writeByte(char c, bool rs){
RodColeman 0:9d621b44ea24 154 char cmd[2]; //led = 1;
RodColeman 0:9d621b44ea24 155 cmd[0]=c>>2; // upper nibble
RodColeman 0:9d621b44ea24 156 cmd[0]=cmd[0] & 0x3c;
RodColeman 0:9d621b44ea24 157 cmd[1]=c<<2; // lower nibble
RodColeman 0:9d621b44ea24 158 cmd[1]=cmd[1] & 0x3c;
RodColeman 0:9d621b44ea24 159 if (rs) {
RodColeman 0:9d621b44ea24 160 cmd[0]=cmd[0] | 0x01;
RodColeman 0:9d621b44ea24 161 cmd[1]=cmd[1] | 0x01;
RodColeman 0:9d621b44ea24 162 }
RodColeman 0:9d621b44ea24 163 _i2c.write( _i2cAddress,cmd,1); // E=0, write upper nibble
RodColeman 0:9d621b44ea24 164 wait_us(1);
RodColeman 0:9d621b44ea24 165 cmd[0]=cmd[0]|0x02; //E=1
RodColeman 0:9d621b44ea24 166 _i2c.write( _i2cAddress, cmd,1);
RodColeman 0:9d621b44ea24 167 wait_us(1);
RodColeman 0:9d621b44ea24 168 cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0
RodColeman 0:9d621b44ea24 169 _i2c.write( _i2cAddress, cmd,1);
RodColeman 0:9d621b44ea24 170 wait_us(1);
RodColeman 0:9d621b44ea24 171 cmd[0]=cmd[1]; //E=0, write lower nibble
RodColeman 0:9d621b44ea24 172 wait_us(1);
RodColeman 0:9d621b44ea24 173 cmd[0]=cmd[0]|0x02; //E=1
RodColeman 0:9d621b44ea24 174 _i2c.write( _i2cAddress, cmd,1);
RodColeman 0:9d621b44ea24 175 wait_us(1);
RodColeman 0:9d621b44ea24 176 cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0
RodColeman 0:9d621b44ea24 177 _i2c.write( _i2cAddress, cmd,1);
RodColeman 0:9d621b44ea24 178 _i2c.write ( _i2cAddress,cmd,1);
RodColeman 0:9d621b44ea24 179 // led = 0;
RodColeman 0:9d621b44ea24 180 wait_us(1);
RodColeman 0:9d621b44ea24 181 }
RodColeman 0:9d621b44ea24 182 //void I2CTextLCD::writeByte(int data, bool rs) {
RodColeman 0:9d621b44ea24 183
RodColeman 0:9d621b44ea24 184
RodColeman 0:9d621b44ea24 185 /*
RodColeman 0:9d621b44ea24 186 writeNibble(data >> 4 , rs);
RodColeman 0:9d621b44ea24 187 writeNibble(data >> 0 , rs);
RodColeman 0:9d621b44ea24 188 RC 2011-8-11. change to d4..d7 - PCF8574 ports P2 .. P5
RodColeman 0:9d621b44ea24 189 */
RodColeman 0:9d621b44ea24 190 //data = data>>2;
RodColeman 0:9d621b44ea24 191 //data = data & 0x3c;
RodColeman 0:9d621b44ea24 192 //writeNibble(data , rs);
RodColeman 0:9d621b44ea24 193 //data = data<<2;
RodColeman 0:9d621b44ea24 194 //data = data & 0x3c;
RodColeman 0:9d621b44ea24 195 //writeNibble(data , rs);
RodColeman 0:9d621b44ea24 196
RodColeman 0:9d621b44ea24 197 void I2CTextLCD::writeCommand(int command) {
RodColeman 0:9d621b44ea24 198 // RS = 0;
RodColeman 0:9d621b44ea24 199 writeByte(command,false);
RodColeman 0:9d621b44ea24 200 }
RodColeman 0:9d621b44ea24 201
RodColeman 0:9d621b44ea24 202 void I2CTextLCD::writeData(int data) {
RodColeman 0:9d621b44ea24 203 //RS = 1
RodColeman 0:9d621b44ea24 204 writeByte(data,true);
RodColeman 0:9d621b44ea24 205
RodColeman 0:9d621b44ea24 206 _column++;
RodColeman 0:9d621b44ea24 207 if (_column >= _columns) {
RodColeman 0:9d621b44ea24 208 newline();
RodColeman 0:9d621b44ea24 209 }
RodColeman 0:9d621b44ea24 210 }
RodColeman 0:9d621b44ea24 211
RodColeman 0:9d621b44ea24 212 /* void I2CTextLCD::writeI2CByte(int data) {
RodColeman 0:9d621b44ea24 213 char cmd[2];
RodColeman 0:9d621b44ea24 214 cmd[0] = (data & 0xFF);
RodColeman 0:9d621b44ea24 215 cmd[1] = (data >> 8);
RodColeman 0:9d621b44ea24 216 _i2c.write(_i2cAddress, cmd, 2);
RodColeman 0:9d621b44ea24 217 */
RodColeman 0:9d621b44ea24 218
RodColeman 0:9d621b44ea24 219
RodColeman 0:9d621b44ea24 220
RodColeman 0:9d621b44ea24 221
RodColeman 0:9d621b44ea24 222
RodColeman 0:9d621b44ea24 223