Updated for more display types. Fixed memoryaddress confusion in address() method. Added new getAddress() method. Added support for UDCs, Backlight control and other features such as control through I2C and SPI port expanders and controllers with native I2C and SPI interfaces. Refactored to fix issue with pins that are default declared as NC.

Dependents:   GPSDevice TestTextLCD SD to Flash Data Transfer DrumMachine ... more

Fork of TextLCD by Simon Ford

Example

Hello World! for the TextLCD

#include "mbed.h"
#include "TextLCD.h"
 
// Host PC Communication channels
Serial pc(USBTX, USBRX); // tx, rx
 
// I2C Communication
I2C i2c_lcd(p28,p27); // SDA, SCL
 
// SPI Communication
SPI spi_lcd(p5, NC, p7); // MOSI, MISO, SCLK

//TextLCD lcd(p15, p16, p17, p18, p19, p20);                // RS, E, D4-D7, LCDType=LCD16x2, BL=NC, E2=NC, LCDTCtrl=HD44780
//TextLCD_SPI lcd(&spi_lcd, p8, TextLCD::LCD40x4);   // SPI bus, 74595 expander, CS pin, LCD Type  
TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD20x4);  // I2C bus, PCF8574 Slaveaddress, LCD Type
//TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD16x2, TextLCD::WS0010); // I2C bus, PCF8574 Slaveaddress, LCD Type, Device Type
//TextLCD_SPI_N lcd(&spi_lcd, p8, p9);               // SPI bus, CS pin, RS pin, LCDType=LCD16x2, BL=NC, LCDTCtrl=ST7032_3V3   
//TextLCD_I2C_N lcd(&i2c_lcd, ST7032_SA, TextLCD::LCD16x2, NC, TextLCD::ST7032_3V3); // I2C bus, Slaveaddress, LCD Type, BL=NC, LCDTCtrl=ST7032_3V3  

int main() {
    pc.printf("LCD Test. Columns=%d, Rows=%d\n\r", lcd.columns(), lcd.rows());
    
    for (int row=0; row<lcd.rows(); row++) {
      int col=0;
      
      pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
//      lcd.putc('-');
      lcd.putc('0' + row);      
      
      for (col=1; col<lcd.columns()-1; col++) {    
        lcd.putc('*');
      }
 
      pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
      lcd.putc('+');
        
    }    
    
// Show cursor as blinking character
    lcd.setCursor(TextLCD::CurOff_BlkOn);
 
// Set and show user defined characters. A maximum of 8 UDCs are supported by the HD44780.
// They are defined by a 5x7 bitpattern. 
    lcd.setUDC(0, (char *) udc_0);  // Show |>
    lcd.putc(0);    
    lcd.setUDC(1, (char *) udc_1);  // Show <|
    lcd.putc(1);    

}

Handbook page

More info is here

Committer:
wim
Date:
Sat Feb 09 15:10:36 2013 +0000
Revision:
13:24506ba22480
Parent:
12:6bf9d9957d31
Child:
14:0c32b66b14b8
First version with I2C interface, refactored code

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