TextLCD

Dependents:   mbed_2019_rx3

Committer:
wim
Date:
Sun Feb 10 18:43:51 2013 +0000
Revision:
14:0c32b66b14b8
Parent:
13:24506ba22480
Child:
15:b70ebfffb258
Added support for I2C and SPI bus interfaces

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 1:ac48b187213c 1 /* mbed TextLCD Library, for a 4-bit LCD based on HD44780
simon 6:e4cb7ddee0d3 2 * Copyright (c) 2007-2010, sford, http://mbed.org
wim 14:0c32b66b14b8 3 * 2013, v01: WH, Added LCD types, fixed LCD address issues, added Cursor and UDCs
wim 14:0c32b66b14b8 4 * 2013, v02: WH, Added I2C and SPI bus interfaces
simon 1:ac48b187213c 5 *
simon 1:ac48b187213c 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
simon 1:ac48b187213c 7 * of this software and associated documentation files (the "Software"), to deal
simon 1:ac48b187213c 8 * in the Software without restriction, including without limitation the rights
simon 1:ac48b187213c 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 1:ac48b187213c 10 * copies of the Software, and to permit persons to whom the Software is
simon 1:ac48b187213c 11 * furnished to do so, subject to the following conditions:
simon 1:ac48b187213c 12 *
simon 1:ac48b187213c 13 * The above copyright notice and this permission notice shall be included in
simon 1:ac48b187213c 14 * all copies or substantial portions of the Software.
simon 1:ac48b187213c 15 *
simon 1:ac48b187213c 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 1:ac48b187213c 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 1:ac48b187213c 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 1:ac48b187213c 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 1:ac48b187213c 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 1:ac48b187213c 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 1:ac48b187213c 22 * THE SOFTWARE.
simon 1:ac48b187213c 23 */
simon 1:ac48b187213c 24
simon 1:ac48b187213c 25 #include "TextLCD.h"
simon 1:ac48b187213c 26 #include "mbed.h"
simon 1:ac48b187213c 27
wim 13:24506ba22480 28 TextLCD::TextLCD(PinName rs, PinName e,
wim 13:24506ba22480 29 PinName d4, PinName d5, PinName d6, PinName d7,
wim 13:24506ba22480 30 LCDType type): _rs(rs), _e(e),
wim 13:24506ba22480 31 _d(d4, d5, d6, d7),
wim 14:0c32b66b14b8 32 _cs(NC),
wim 13:24506ba22480 33 _type(type) {
wim 13:24506ba22480 34
wim 13:24506ba22480 35
wim 13:24506ba22480 36 _busType = _PinBus;
wim 13:24506ba22480 37
wim 13:24506ba22480 38 _init();
wim 13:24506ba22480 39
wim 13:24506ba22480 40 }
wim 13:24506ba22480 41
wim 13:24506ba22480 42
wim 13:24506ba22480 43 TextLCD::TextLCD(I2C *i2c, char deviceAddress, LCDType type) :
wim 13:24506ba22480 44 _rs(NC), _e(NC), _d(NC),
wim 14:0c32b66b14b8 45 _cs(NC),
wim 13:24506ba22480 46 _i2c(i2c),
simon 1:ac48b187213c 47 _type(type) {
wim 13:24506ba22480 48
wim 13:24506ba22480 49 _slaveAddress = deviceAddress;
wim 13:24506ba22480 50 _busType = _I2CBus;
simon 1:ac48b187213c 51
wim 13:24506ba22480 52
wim 13:24506ba22480 53 // Init the portexpander bus
wim 13:24506ba22480 54 _lcd_bus = 0x80;
wim 13:24506ba22480 55
wim 13:24506ba22480 56 // write the new data to the portexpander
wim 13:24506ba22480 57 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 13:24506ba22480 58
wim 13:24506ba22480 59 _init();
wim 13:24506ba22480 60
wim 13:24506ba22480 61 }
simon 1:ac48b187213c 62
wim 14:0c32b66b14b8 63
wim 14:0c32b66b14b8 64 TextLCD::TextLCD(SPI *spi, PinName cs, LCDType type) :
wim 14:0c32b66b14b8 65 _rs(NC), _e(NC), _d(NC),
wim 14:0c32b66b14b8 66 _spi(spi),
wim 14:0c32b66b14b8 67 _cs(cs),
wim 14:0c32b66b14b8 68 _type(type) {
wim 14:0c32b66b14b8 69
wim 14:0c32b66b14b8 70 _busType = _SPIBus;
wim 14:0c32b66b14b8 71
wim 14:0c32b66b14b8 72 // Setup the spi for 8 bit data, low steady state clock,
wim 14:0c32b66b14b8 73 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 14:0c32b66b14b8 74 _spi->format(8,0);
wim 14:0c32b66b14b8 75 _spi->frequency(500000);
wim 14:0c32b66b14b8 76 //_spi.frequency(1000000);
wim 14:0c32b66b14b8 77
wim 14:0c32b66b14b8 78
wim 14:0c32b66b14b8 79 // Init the portexpander bus
wim 14:0c32b66b14b8 80 _lcd_bus = 0x80;
wim 14:0c32b66b14b8 81
wim 14:0c32b66b14b8 82 // write the new data to the portexpander
wim 14:0c32b66b14b8 83 _setCS(false);
wim 14:0c32b66b14b8 84 _spi->write(_lcd_bus);
wim 14:0c32b66b14b8 85 _setCS(true);
wim 14:0c32b66b14b8 86
wim 14:0c32b66b14b8 87 _init();
wim 14:0c32b66b14b8 88
wim 14:0c32b66b14b8 89 }
wim 14:0c32b66b14b8 90
wim 14:0c32b66b14b8 91
wim 14:0c32b66b14b8 92 /* Init the LCD controller
wim 13:24506ba22480 93 * 4-bit mode, number of lines, no cursor etc
wim 13:24506ba22480 94 * Clear display
wim 13:24506ba22480 95 */
wim 13:24506ba22480 96 void TextLCD::_init() {
wim 13:24506ba22480 97 // _e = 1;
wim 13:24506ba22480 98 // _rs = 0; // command mode
wim 13:24506ba22480 99
wim 13:24506ba22480 100 _setEnable(true);
wim 13:24506ba22480 101 _setRS(false); // command mode
wim 13:24506ba22480 102
wim 14:0c32b66b14b8 103 // wait(0.015); // Wait 15ms to ensure powered up
wim 14:0c32b66b14b8 104 wait_ms(15); // Wait 15ms to ensure powered up
simon 1:ac48b187213c 105
simon 1:ac48b187213c 106 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
simon 1:ac48b187213c 107 for (int i=0; i<3; i++) {
wim 13:24506ba22480 108 _writeByte(0x3);
wim 14:0c32b66b14b8 109 // wait(0.00164); // this command takes 1.64ms, so wait for it
wim 14:0c32b66b14b8 110 wait_ms(10); // this command takes 1.64ms, so wait for it
simon 1:ac48b187213c 111 }
wim 13:24506ba22480 112 _writeByte(0x2); // 4-bit mode
wim 14:0c32b66b14b8 113 // wait(0.000040f); // most instructions take 40us
wim 14:0c32b66b14b8 114 wait_us(40); // most instructions take 40us
wim 14:0c32b66b14b8 115
wim 10:dd9b3a696acd 116 // Display is now in 4-bit mode
wim 10:dd9b3a696acd 117 switch (_type) {
wim 10:dd9b3a696acd 118 case LCD8x1:
wim 13:24506ba22480 119 _writeCommand(0x20); // Function set 001 BW N F - -
wim 13:24506ba22480 120 // N=0 (1 line)
wim 13:24506ba22480 121 // F=0 (5x7 dots font)
wim 10:dd9b3a696acd 122 break;
wim 10:dd9b3a696acd 123
wim 10:dd9b3a696acd 124 case LCD24x4:
wim 10:dd9b3a696acd 125 // Special mode for KS0078
wim 13:24506ba22480 126 _writeCommand(0x2A); // Function set 001 BW N RE DH REV
wim 13:24506ba22480 127 // N=1 (Dont care for KS0078)
wim 13:24506ba22480 128 // RE=0 (Extended Regs, special mode for KS0078)
wim 13:24506ba22480 129 // DH=1 (Disp shift, special mode for KS0078)
wim 13:24506ba22480 130 // REV=0 (Reverse, special mode for KS0078)
wim 10:dd9b3a696acd 131
wim 13:24506ba22480 132 _writeCommand(0x2E); // Function set 001 BW N RE DH REV
wim 13:24506ba22480 133 // N=1 (Dont care for KS0078)
wim 13:24506ba22480 134 // RE=1 (Ena Extended Regs, special mode for KS0078)
wim 13:24506ba22480 135 // DH=1 (Disp shift, special mode for KS0078)
wim 13:24506ba22480 136 // REV=0 (Reverse, special mode for KS0078)
wim 10:dd9b3a696acd 137
wim 13:24506ba22480 138 _writeCommand(0x09); // Ext Function set 0000 1 FW BW NW
wim 13:24506ba22480 139 // FW=0 (5-dot font, special mode for KS0078)
wim 13:24506ba22480 140 // BW=0 (Cur BW invert disable, special mode for KS0078)
wim 13:24506ba22480 141 // NW=1 (4 Line, special mode for KS0078)
wim 10:dd9b3a696acd 142
wim 13:24506ba22480 143 _writeCommand(0x2A); // Function set 001 BW N RE DH REV
wim 13:24506ba22480 144 // N=1 (Dont care for KS0078)
wim 13:24506ba22480 145 // RE=0 (Dis. Extended Regs, special mode for KS0078)
wim 13:24506ba22480 146 // DH=1 (Disp shift, special mode for KS0078)
wim 13:24506ba22480 147 // REV=0 (Reverse, special mode for KS0078)
wim 10:dd9b3a696acd 148 break;
wim 10:dd9b3a696acd 149
wim 10:dd9b3a696acd 150 default:
wim 13:24506ba22480 151 _writeCommand(0x28); // Function set 001 BW N F - -
wim 13:24506ba22480 152 // N=1 (2 lines)
wim 13:24506ba22480 153 // F=0 (5x7 dots font)
wim 13:24506ba22480 154 // - (Don't care)
wim 10:dd9b3a696acd 155
wim 10:dd9b3a696acd 156 break;
wim 10:dd9b3a696acd 157 }
wim 10:dd9b3a696acd 158
wim 13:24506ba22480 159 _writeCommand(0x06); // Entry Mode 0000 01 CD S
wim 13:24506ba22480 160 // Cursor Direction and Display Shift
wim 13:24506ba22480 161 // CD=1 (Cur incr)
wim 13:24506ba22480 162 // S=0 (No display shift)
wim 10:dd9b3a696acd 163
wim 13:24506ba22480 164 // _writeCommand(0x0C); // Display Ctrl 0000 1 D C B
wim 13:24506ba22480 165 // // Display On, Cursor Off, Blink Off
wim 13:24506ba22480 166 setCursor(TextLCD::CurOff_BlkOff);
wim 11:9ec02df863a1 167
wim 10:dd9b3a696acd 168 cls();
simon 1:ac48b187213c 169 }
simon 1:ac48b187213c 170
wim 8:03116f75b66e 171
wim 13:24506ba22480 172 void TextLCD::_character(int column, int row, int c) {
wim 8:03116f75b66e 173 int addr = getAddress(column, row);
wim 8:03116f75b66e 174
wim 13:24506ba22480 175 _writeCommand(0x80 | addr);
wim 13:24506ba22480 176 _writeData(c);
simon 1:ac48b187213c 177 }
simon 1:ac48b187213c 178
wim 8:03116f75b66e 179
simon 1:ac48b187213c 180 void TextLCD::cls() {
wim 13:24506ba22480 181 _writeCommand(0x01); // cls, and set cursor to 0
wim 14:0c32b66b14b8 182 // wait(0.00164f); // This command takes 1.64 ms
wim 14:0c32b66b14b8 183 wait_ms(10); // The CLS command takes 1.64 ms.
wim 14:0c32b66b14b8 184 // Since we are not using the Busy flag, Lets be safe and take 10 ms
simon 1:ac48b187213c 185 locate(0, 0);
simon 1:ac48b187213c 186 }
simon 1:ac48b187213c 187
simon 1:ac48b187213c 188 void TextLCD::locate(int column, int row) {
simon 1:ac48b187213c 189 _column = column;
simon 1:ac48b187213c 190 _row = row;
simon 1:ac48b187213c 191 }
simon 1:ac48b187213c 192
simon 1:ac48b187213c 193 int TextLCD::_putc(int value) {
simon 1:ac48b187213c 194 if (value == '\n') {
simon 1:ac48b187213c 195 _column = 0;
simon 1:ac48b187213c 196 _row++;
simon 1:ac48b187213c 197 if (_row >= rows()) {
simon 1:ac48b187213c 198 _row = 0;
simon 1:ac48b187213c 199 }
simon 1:ac48b187213c 200 } else {
wim 13:24506ba22480 201 _character(_column, _row, value);
simon 1:ac48b187213c 202 _column++;
simon 1:ac48b187213c 203 if (_column >= columns()) {
simon 1:ac48b187213c 204 _column = 0;
simon 1:ac48b187213c 205 _row++;
simon 1:ac48b187213c 206 if (_row >= rows()) {
simon 1:ac48b187213c 207 _row = 0;
simon 1:ac48b187213c 208 }
simon 1:ac48b187213c 209 }
simon 1:ac48b187213c 210 }
simon 1:ac48b187213c 211 return value;
simon 1:ac48b187213c 212 }
simon 1:ac48b187213c 213
simon 1:ac48b187213c 214 int TextLCD::_getc() {
simon 1:ac48b187213c 215 return -1;
simon 1:ac48b187213c 216 }
simon 1:ac48b187213c 217
wim 13:24506ba22480 218
wim 13:24506ba22480 219 void TextLCD::_setEnable(bool value) {
wim 13:24506ba22480 220
wim 13:24506ba22480 221 switch(_busType) {
wim 13:24506ba22480 222 case _PinBus :
wim 13:24506ba22480 223 if (value)
wim 13:24506ba22480 224 _e = 1; // Set E bit
wim 13:24506ba22480 225 else
wim 13:24506ba22480 226 _e = 0; // Reset E bit
wim 13:24506ba22480 227
wim 13:24506ba22480 228 break;
wim 13:24506ba22480 229
wim 13:24506ba22480 230 case _I2CBus :
wim 14:0c32b66b14b8 231 if (value)
wim 14:0c32b66b14b8 232 _lcd_bus |= D_LCD_E; // Set E bit
wim 14:0c32b66b14b8 233 else
wim 14:0c32b66b14b8 234 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 13:24506ba22480 235
wim 14:0c32b66b14b8 236 // write the new data to the portexpander
wim 14:0c32b66b14b8 237 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 13:24506ba22480 238
wim 13:24506ba22480 239 break;
wim 13:24506ba22480 240
wim 13:24506ba22480 241 case _SPIBus :
wim 14:0c32b66b14b8 242 if (value)
wim 14:0c32b66b14b8 243 _lcd_bus |= D_LCD_E; // Set E bit
wim 14:0c32b66b14b8 244 else
wim 14:0c32b66b14b8 245 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 14:0c32b66b14b8 246
wim 14:0c32b66b14b8 247 // write the new data to the portexpander
wim 14:0c32b66b14b8 248 _setCS(false);
wim 14:0c32b66b14b8 249 _spi->write(_lcd_bus);
wim 14:0c32b66b14b8 250 _setCS(true);
wim 14:0c32b66b14b8 251
wim 13:24506ba22480 252 break;
wim 13:24506ba22480 253 }
wim 13:24506ba22480 254 }
wim 13:24506ba22480 255
wim 13:24506ba22480 256 void TextLCD::_setRS(bool value) {
wim 13:24506ba22480 257
wim 13:24506ba22480 258 switch(_busType) {
wim 13:24506ba22480 259 case _PinBus :
wim 13:24506ba22480 260 if (value)
wim 13:24506ba22480 261 _rs = 1; // Set RS bit
wim 13:24506ba22480 262 else
wim 13:24506ba22480 263 _rs = 0; // Reset RS bit
wim 13:24506ba22480 264
wim 13:24506ba22480 265 break;
wim 13:24506ba22480 266
wim 13:24506ba22480 267 case _I2CBus :
wim 14:0c32b66b14b8 268 if (value)
wim 14:0c32b66b14b8 269 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 14:0c32b66b14b8 270 else
wim 14:0c32b66b14b8 271 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 13:24506ba22480 272
wim 14:0c32b66b14b8 273 // write the new data to the portexpander
wim 14:0c32b66b14b8 274 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 13:24506ba22480 275
wim 13:24506ba22480 276 break;
wim 13:24506ba22480 277
wim 13:24506ba22480 278 case _SPIBus :
wim 14:0c32b66b14b8 279 if (value)
wim 14:0c32b66b14b8 280 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 14:0c32b66b14b8 281 else
wim 14:0c32b66b14b8 282 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 14:0c32b66b14b8 283
wim 14:0c32b66b14b8 284 // write the new data to the portexpander
wim 14:0c32b66b14b8 285 _setCS(false);
wim 14:0c32b66b14b8 286 _spi->write(_lcd_bus);
wim 14:0c32b66b14b8 287 _setCS(true);
wim 14:0c32b66b14b8 288
wim 13:24506ba22480 289 break;
wim 13:24506ba22480 290 }
wim 13:24506ba22480 291
wim 13:24506ba22480 292 }
wim 13:24506ba22480 293
wim 13:24506ba22480 294 void TextLCD::_setData(int value) {
wim 13:24506ba22480 295 int data;
wim 13:24506ba22480 296
wim 13:24506ba22480 297 switch(_busType) {
wim 13:24506ba22480 298 case _PinBus :
wim 13:24506ba22480 299 _d = value & 0x0F; // Write Databits
wim 13:24506ba22480 300
wim 13:24506ba22480 301 break;
wim 13:24506ba22480 302
wim 13:24506ba22480 303 case _I2CBus :
wim 13:24506ba22480 304 data = value & 0x0F;
wim 13:24506ba22480 305 if (data & 0x01)
wim 13:24506ba22480 306 _lcd_bus |= D_LCD_D4; // Set Databit
wim 13:24506ba22480 307 else
wim 13:24506ba22480 308 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 13:24506ba22480 309
wim 13:24506ba22480 310 if (data & 0x02)
wim 13:24506ba22480 311 _lcd_bus |= D_LCD_D5; // Set Databit
wim 13:24506ba22480 312 else
wim 13:24506ba22480 313 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 13:24506ba22480 314
wim 13:24506ba22480 315 if (data & 0x04)
wim 13:24506ba22480 316 _lcd_bus |= D_LCD_D6; // Set Databit
wim 13:24506ba22480 317 else
wim 13:24506ba22480 318 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 13:24506ba22480 319
wim 13:24506ba22480 320 if (data & 0x08)
wim 13:24506ba22480 321 _lcd_bus |= D_LCD_D7; // Set Databit
wim 13:24506ba22480 322 else
wim 13:24506ba22480 323 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 13:24506ba22480 324
wim 13:24506ba22480 325 // write the new data to the portexpander
wim 13:24506ba22480 326 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 13:24506ba22480 327
wim 13:24506ba22480 328 break;
wim 13:24506ba22480 329
wim 13:24506ba22480 330 case _SPIBus :
wim 14:0c32b66b14b8 331
wim 14:0c32b66b14b8 332 data = value & 0x0F;
wim 14:0c32b66b14b8 333 if (data & 0x01)
wim 14:0c32b66b14b8 334 _lcd_bus |= D_LCD_D4; // Set Databit
wim 14:0c32b66b14b8 335 else
wim 14:0c32b66b14b8 336 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 14:0c32b66b14b8 337
wim 14:0c32b66b14b8 338 if (data & 0x02)
wim 14:0c32b66b14b8 339 _lcd_bus |= D_LCD_D5; // Set Databit
wim 14:0c32b66b14b8 340 else
wim 14:0c32b66b14b8 341 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 14:0c32b66b14b8 342
wim 14:0c32b66b14b8 343 if (data & 0x04)
wim 14:0c32b66b14b8 344 _lcd_bus |= D_LCD_D6; // Set Databit
wim 14:0c32b66b14b8 345 else
wim 14:0c32b66b14b8 346 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 14:0c32b66b14b8 347
wim 14:0c32b66b14b8 348 if (data & 0x08)
wim 14:0c32b66b14b8 349 _lcd_bus |= D_LCD_D7; // Set Databit
wim 14:0c32b66b14b8 350 else
wim 14:0c32b66b14b8 351 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 14:0c32b66b14b8 352
wim 14:0c32b66b14b8 353 // write the new data to the portexpander
wim 14:0c32b66b14b8 354 _setCS(false);
wim 14:0c32b66b14b8 355 _spi->write(_lcd_bus);
wim 14:0c32b66b14b8 356 _setCS(true);
wim 14:0c32b66b14b8 357
wim 14:0c32b66b14b8 358 break;
wim 13:24506ba22480 359 }
wim 13:24506ba22480 360
wim 13:24506ba22480 361 }
wim 13:24506ba22480 362
wim 13:24506ba22480 363
wim 14:0c32b66b14b8 364 // Set CS line. Only used for SPI bus
wim 14:0c32b66b14b8 365 void TextLCD::_setCS(bool value) {
wim 14:0c32b66b14b8 366
wim 14:0c32b66b14b8 367 if (value)
wim 14:0c32b66b14b8 368 _cs = 1; // Set CS pin
wim 14:0c32b66b14b8 369 else
wim 14:0c32b66b14b8 370 _cs = 0; // Reset CS pin
wim 14:0c32b66b14b8 371
wim 14:0c32b66b14b8 372 }
wim 14:0c32b66b14b8 373
wim 14:0c32b66b14b8 374
wim 13:24506ba22480 375
wim 13:24506ba22480 376 void TextLCD::_writeByte(int value) {
wim 13:24506ba22480 377 // _d = value >> 4;
wim 13:24506ba22480 378 _setData(value >> 4);
wim 14:0c32b66b14b8 379 // wait(0.000040f); // most instructions take 40us
wim 14:0c32b66b14b8 380 wait_us(40); // most instructions take 40us
wim 13:24506ba22480 381 // _e = 0;
wim 13:24506ba22480 382 _setEnable(false);
wim 14:0c32b66b14b8 383 // wait(0.000040f);
wim 14:0c32b66b14b8 384 wait_us(40); // most instructions take 40us
wim 13:24506ba22480 385 // _e = 1;
wim 13:24506ba22480 386 _setEnable(true);
wim 13:24506ba22480 387 // _d = value >> 0;
wim 13:24506ba22480 388 _setData(value >> 0);
wim 14:0c32b66b14b8 389 // wait(0.000040f);
wim 14:0c32b66b14b8 390 wait_us(40); // most instructions take 40us
wim 13:24506ba22480 391 // _e = 0;
wim 13:24506ba22480 392 _setEnable(false);
wim 14:0c32b66b14b8 393 // wait(0.000040f); // most instructions take 40us
wim 14:0c32b66b14b8 394 wait_us(40); // most instructions take 40us
wim 13:24506ba22480 395 // _e = 1;
wim 13:24506ba22480 396 _setEnable(true);
simon 1:ac48b187213c 397 }
simon 1:ac48b187213c 398
wim 13:24506ba22480 399 void TextLCD::_writeCommand(int command) {
wim 13:24506ba22480 400 // _rs = 0;
wim 13:24506ba22480 401 _setRS(false);
wim 13:24506ba22480 402 _writeByte(command);
simon 1:ac48b187213c 403 }
simon 1:ac48b187213c 404
wim 13:24506ba22480 405 void TextLCD::_writeData(int data) {
wim 13:24506ba22480 406 // _rs = 1;
wim 13:24506ba22480 407 _setRS(true);
wim 13:24506ba22480 408 _writeByte(data);
simon 1:ac48b187213c 409 }
simon 1:ac48b187213c 410
wim 8:03116f75b66e 411
wim 8:03116f75b66e 412 #if (0)
wim 8:03116f75b66e 413 // This is the original method.
wim 8:03116f75b66e 414 // It is confusing since it returns the memoryaddress or-ed with the set memorycommand 0x80.
wim 8:03116f75b66e 415 // Left it in here for compatibility with older code. New applications should use getAddress() instead.
wim 8:03116f75b66e 416 //
wim 13:24506ba22480 417 int TextLCD::_address(int column, int row) {
simon 1:ac48b187213c 418 switch (_type) {
simon 1:ac48b187213c 419 case LCD20x4:
simon 1:ac48b187213c 420 switch (row) {
simon 1:ac48b187213c 421 case 0:
simon 1:ac48b187213c 422 return 0x80 + column;
simon 1:ac48b187213c 423 case 1:
simon 1:ac48b187213c 424 return 0xc0 + column;
simon 1:ac48b187213c 425 case 2:
simon 1:ac48b187213c 426 return 0x94 + column;
simon 1:ac48b187213c 427 case 3:
simon 1:ac48b187213c 428 return 0xd4 + column;
simon 1:ac48b187213c 429 }
simon 1:ac48b187213c 430 case LCD16x2B:
simon 4:bf5b706f8d32 431 return 0x80 + (row * 40) + column;
simon 1:ac48b187213c 432 case LCD16x2:
simon 1:ac48b187213c 433 case LCD20x2:
simon 1:ac48b187213c 434 default:
simon 4:bf5b706f8d32 435 return 0x80 + (row * 0x40) + column;
simon 1:ac48b187213c 436 }
simon 1:ac48b187213c 437 }
wim 8:03116f75b66e 438 #endif
wim 8:03116f75b66e 439
wim 8:03116f75b66e 440
wim 8:03116f75b66e 441 // This replaces the original method.
wim 8:03116f75b66e 442 // Left it in here for compatibility with older code. New applications should use getAddress() instead.
wim 13:24506ba22480 443 int TextLCD::_address(int column, int row) {
wim 8:03116f75b66e 444 return 0x80 | getAddress(column, row);
wim 8:03116f75b66e 445 }
wim 8:03116f75b66e 446
wim 8:03116f75b66e 447 // This is new method to return the memory address based on row, column and displaytype.
wim 8:03116f75b66e 448 //
wim 8:03116f75b66e 449 int TextLCD::getAddress(int column, int row) {
wim 8:03116f75b66e 450
wim 8:03116f75b66e 451 switch (_type) {
wim 8:03116f75b66e 452 case LCD8x1:
wim 8:03116f75b66e 453 return 0x00 + column;
wim 8:03116f75b66e 454
wim 13:24506ba22480 455 case LCD16x1:
wim 13:24506ba22480 456 // LCD16x1 is a special layout of LCD8x2
wim 13:24506ba22480 457 if (column<8)
wim 13:24506ba22480 458 return 0x00 + column;
wim 13:24506ba22480 459 else
wim 13:24506ba22480 460 return 0x40 + (column - 8);
wim 13:24506ba22480 461
wim 8:03116f75b66e 462 case LCD16x4:
wim 8:03116f75b66e 463 switch (row) {
wim 8:03116f75b66e 464 case 0:
wim 8:03116f75b66e 465 return 0x00 + column;
wim 8:03116f75b66e 466 case 1:
wim 8:03116f75b66e 467 return 0x40 + column;
wim 8:03116f75b66e 468 case 2:
wim 8:03116f75b66e 469 return 0x10 + column;
wim 8:03116f75b66e 470 case 3:
wim 8:03116f75b66e 471 return 0x50 + column;
wim 8:03116f75b66e 472 }
wim 8:03116f75b66e 473
wim 8:03116f75b66e 474 case LCD20x4:
wim 8:03116f75b66e 475 switch (row) {
wim 8:03116f75b66e 476 case 0:
wim 8:03116f75b66e 477 return 0x00 + column;
wim 8:03116f75b66e 478 case 1:
wim 8:03116f75b66e 479 return 0x40 + column;
wim 8:03116f75b66e 480 case 2:
wim 8:03116f75b66e 481 return 0x14 + column;
wim 8:03116f75b66e 482 case 3:
wim 8:03116f75b66e 483 return 0x54 + column;
wim 8:03116f75b66e 484 }
wim 8:03116f75b66e 485
wim 10:dd9b3a696acd 486 // Special mode for KS0078
wim 10:dd9b3a696acd 487 case LCD24x4:
wim 10:dd9b3a696acd 488 switch (row) {
wim 10:dd9b3a696acd 489 case 0:
wim 10:dd9b3a696acd 490 return 0x00 + column;
wim 10:dd9b3a696acd 491 case 1:
wim 10:dd9b3a696acd 492 return 0x20 + column;
wim 10:dd9b3a696acd 493 case 2:
wim 10:dd9b3a696acd 494 return 0x40 + column;
wim 10:dd9b3a696acd 495 case 3:
wim 10:dd9b3a696acd 496 return 0x60 + column;
wim 10:dd9b3a696acd 497 }
wim 10:dd9b3a696acd 498
wim 8:03116f75b66e 499 // Not sure about this one, seems wrong.
wim 8:03116f75b66e 500 case LCD16x2B:
wim 8:03116f75b66e 501 return 0x00 + (row * 40) + column;
wim 8:03116f75b66e 502
wim 8:03116f75b66e 503 case LCD8x2:
wim 8:03116f75b66e 504 case LCD16x2:
wim 8:03116f75b66e 505 case LCD20x2:
wim 8:03116f75b66e 506 case LCD24x2:
wim 9:0893d986e717 507 case LCD40x2:
wim 8:03116f75b66e 508 return 0x00 + (row * 0x40) + column;
wim 8:03116f75b66e 509
wim 8:03116f75b66e 510 // Should never get here.
wim 8:03116f75b66e 511 default:
wim 8:03116f75b66e 512 return 0x00;
wim 8:03116f75b66e 513 }
wim 8:03116f75b66e 514 }
wim 8:03116f75b66e 515
wim 8:03116f75b66e 516
wim 13:24506ba22480 517 // Added for consistency. Set row, column and update memoryaddress.
wim 8:03116f75b66e 518 //
wim 8:03116f75b66e 519 void TextLCD::setAddress(int column, int row) {
wim 8:03116f75b66e 520
wim 8:03116f75b66e 521 locate(column, row);
wim 8:03116f75b66e 522
wim 8:03116f75b66e 523 int addr = getAddress(column, row);
wim 8:03116f75b66e 524
wim 13:24506ba22480 525 _writeCommand(0x80 | addr);
wim 8:03116f75b66e 526 }
simon 1:ac48b187213c 527
simon 1:ac48b187213c 528 int TextLCD::columns() {
simon 1:ac48b187213c 529 switch (_type) {
wim 8:03116f75b66e 530 case LCD8x1:
wim 8:03116f75b66e 531 case LCD8x2:
wim 8:03116f75b66e 532 return 8;
wim 8:03116f75b66e 533
wim 13:24506ba22480 534 case LCD16x1:
simon 1:ac48b187213c 535 case LCD16x2:
simon 1:ac48b187213c 536 case LCD16x2B:
wim 8:03116f75b66e 537 case LCD16x4:
wim 8:03116f75b66e 538 return 16;
wim 8:03116f75b66e 539
wim 8:03116f75b66e 540 case LCD20x2:
wim 8:03116f75b66e 541 case LCD20x4:
wim 8:03116f75b66e 542 return 20;
wim 8:03116f75b66e 543
wim 8:03116f75b66e 544 case LCD24x2:
wim 10:dd9b3a696acd 545 case LCD24x4:
wim 8:03116f75b66e 546 return 24;
wim 9:0893d986e717 547
wim 9:0893d986e717 548 case LCD40x2:
wim 9:0893d986e717 549 return 40;
wim 8:03116f75b66e 550
wim 8:03116f75b66e 551 // Should never get here.
simon 1:ac48b187213c 552 default:
wim 8:03116f75b66e 553 return 0;
simon 1:ac48b187213c 554 }
simon 1:ac48b187213c 555 }
simon 1:ac48b187213c 556
simon 1:ac48b187213c 557 int TextLCD::rows() {
simon 1:ac48b187213c 558 switch (_type) {
wim 8:03116f75b66e 559 case LCD8x1:
wim 13:24506ba22480 560 case LCD16x1:
wim 8:03116f75b66e 561 return 1;
wim 8:03116f75b66e 562
wim 8:03116f75b66e 563 case LCD8x2:
simon 1:ac48b187213c 564 case LCD16x2:
simon 1:ac48b187213c 565 case LCD16x2B:
simon 1:ac48b187213c 566 case LCD20x2:
wim 8:03116f75b66e 567 case LCD24x2:
wim 9:0893d986e717 568 case LCD40x2:
wim 8:03116f75b66e 569 return 2;
wim 8:03116f75b66e 570
wim 8:03116f75b66e 571 case LCD16x4:
wim 8:03116f75b66e 572 case LCD20x4:
wim 10:dd9b3a696acd 573 case LCD24x4:
wim 8:03116f75b66e 574 return 4;
wim 12:6bf9d9957d31 575
wim 12:6bf9d9957d31 576 // Should never get here.
simon 1:ac48b187213c 577 default:
wim 8:03116f75b66e 578 return 0;
simon 1:ac48b187213c 579 }
simon 1:ac48b187213c 580 }
wim 10:dd9b3a696acd 581
wim 10:dd9b3a696acd 582
wim 13:24506ba22480 583 void TextLCD::setCursor(TextLCD::LCDCursor show) {
wim 10:dd9b3a696acd 584
wim 10:dd9b3a696acd 585 switch (show) {
wim 13:24506ba22480 586 case CurOff_BlkOff : _writeCommand(0x0C); // Cursor off and Blink Off
wim 11:9ec02df863a1 587 wait_us(40);
wim 11:9ec02df863a1 588 _cursor = show;
wim 11:9ec02df863a1 589 break;
wim 11:9ec02df863a1 590
wim 13:24506ba22480 591 case CurOn_BlkOff : _writeCommand(0x0E); // Cursor on and Blink Off
wim 11:9ec02df863a1 592 wait_us(40);
wim 11:9ec02df863a1 593 _cursor = show;
wim 11:9ec02df863a1 594 break;
wim 11:9ec02df863a1 595
wim 13:24506ba22480 596 case CurOff_BlkOn : _writeCommand(0x0D); // Cursor off and Blink On
wim 11:9ec02df863a1 597 wait_us(40);
wim 11:9ec02df863a1 598 _cursor = show;
wim 11:9ec02df863a1 599 break;
wim 11:9ec02df863a1 600
wim 13:24506ba22480 601 case CurOn_BlkOn : _writeCommand(0x0F); // Cursor on and Blink char
wim 11:9ec02df863a1 602 wait_us(40);
wim 11:9ec02df863a1 603 _cursor = show;
wim 11:9ec02df863a1 604 break;
wim 11:9ec02df863a1 605
wim 12:6bf9d9957d31 606 // Should never get here.
wim 10:dd9b3a696acd 607 default :
wim 11:9ec02df863a1 608 break;
wim 10:dd9b3a696acd 609
wim 10:dd9b3a696acd 610 }
wim 11:9ec02df863a1 611
wim 10:dd9b3a696acd 612 }
wim 10:dd9b3a696acd 613
wim 10:dd9b3a696acd 614
wim 11:9ec02df863a1 615 void TextLCD::setUDC(unsigned char c, char *udc_data) {
wim 13:24506ba22480 616 _writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address
wim 11:9ec02df863a1 617
wim 11:9ec02df863a1 618 for (int i=0; i<8; i++) {
wim 13:24506ba22480 619 _writeData(*udc_data++);
wim 11:9ec02df863a1 620 }
wim 11:9ec02df863a1 621 }
wim 10:dd9b3a696acd 622
wim 10:dd9b3a696acd 623