1

Dependents:   Program_R11

Committer:
wim
Date:
Tue Feb 19 22:09:09 2013 +0000
Revision:
15:b70ebfffb258
Parent:
14:0c32b66b14b8
Child:
16:c276b75e6585
Working testversion for 40x4.; Fixed cursor problems.; Fixed UDC problems, always return to DD RAM.

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
wim 15:b70ebfffb258 5 * 2013, v03: WH, Added support for LCD40x4 which uses 2 controllers
simon 1:ac48b187213c 6 *
simon 1:ac48b187213c 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
simon 1:ac48b187213c 8 * of this software and associated documentation files (the "Software"), to deal
simon 1:ac48b187213c 9 * in the Software without restriction, including without limitation the rights
simon 1:ac48b187213c 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 1:ac48b187213c 11 * copies of the Software, and to permit persons to whom the Software is
simon 1:ac48b187213c 12 * furnished to do so, subject to the following conditions:
simon 1:ac48b187213c 13 *
simon 1:ac48b187213c 14 * The above copyright notice and this permission notice shall be included in
simon 1:ac48b187213c 15 * all copies or substantial portions of the Software.
simon 1:ac48b187213c 16 *
simon 1:ac48b187213c 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 1:ac48b187213c 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 1:ac48b187213c 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 1:ac48b187213c 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 1:ac48b187213c 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 1:ac48b187213c 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 1:ac48b187213c 23 * THE SOFTWARE.
simon 1:ac48b187213c 24 */
simon 1:ac48b187213c 25
simon 1:ac48b187213c 26 #include "TextLCD.h"
simon 1:ac48b187213c 27 #include "mbed.h"
simon 1:ac48b187213c 28
wim 15:b70ebfffb258 29
wim 15:b70ebfffb258 30 /* Create a TextLCD interface for using regular mbed pins
wim 15:b70ebfffb258 31 *
wim 15:b70ebfffb258 32 * @param rs Instruction/data control line
wim 15:b70ebfffb258 33 * @param e Enable line (clock)
wim 15:b70ebfffb258 34 * @param d4-d7 Data lines for using as a 4-bit interface
wim 15:b70ebfffb258 35 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 15:b70ebfffb258 36 * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
wim 15:b70ebfffb258 37 */
wim 13:24506ba22480 38 TextLCD::TextLCD(PinName rs, PinName e,
wim 13:24506ba22480 39 PinName d4, PinName d5, PinName d6, PinName d7,
wim 15:b70ebfffb258 40 LCDType type, PinName e2) : _rs(rs), _e(e), _e2(e2),
wim 15:b70ebfffb258 41 _d(d4, d5, d6, d7),
wim 15:b70ebfffb258 42 _cs(NC),
wim 15:b70ebfffb258 43 _type(type) {
wim 13:24506ba22480 44
wim 13:24506ba22480 45 _busType = _PinBus;
wim 13:24506ba22480 46
wim 13:24506ba22480 47 _init();
wim 13:24506ba22480 48
wim 13:24506ba22480 49 }
wim 13:24506ba22480 50
wim 15:b70ebfffb258 51 /* Create a TextLCD interface using an I2C PC8574 portexpander
wim 15:b70ebfffb258 52 *
wim 15:b70ebfffb258 53 * @param i2c I2C Bus
wim 15:b70ebfffb258 54 * @param deviceAddress I2C slave address (PCF8574)
wim 15:b70ebfffb258 55 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 15:b70ebfffb258 56 */
wim 13:24506ba22480 57 TextLCD::TextLCD(I2C *i2c, char deviceAddress, LCDType type) :
wim 15:b70ebfffb258 58 _rs(NC), _e(NC), _e2(NC),
wim 15:b70ebfffb258 59 _d(NC),
wim 15:b70ebfffb258 60 _i2c(i2c),
wim 15:b70ebfffb258 61 _cs(NC),
simon 1:ac48b187213c 62 _type(type) {
wim 15:b70ebfffb258 63
wim 13:24506ba22480 64 _slaveAddress = deviceAddress;
wim 13:24506ba22480 65 _busType = _I2CBus;
simon 1:ac48b187213c 66
wim 13:24506ba22480 67
wim 13:24506ba22480 68 // Init the portexpander bus
wim 15:b70ebfffb258 69 _lcd_bus = D_LCD_BUS_DEF;
wim 13:24506ba22480 70
wim 13:24506ba22480 71 // write the new data to the portexpander
wim 13:24506ba22480 72 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 13:24506ba22480 73
wim 13:24506ba22480 74 _init();
wim 13:24506ba22480 75
wim 13:24506ba22480 76 }
simon 1:ac48b187213c 77
wim 15:b70ebfffb258 78 /* Create a TextLCD interface using an SPI 74595 portexpander
wim 15:b70ebfffb258 79 *
wim 15:b70ebfffb258 80 * @param spi SPI Bus
wim 15:b70ebfffb258 81 * @param cs chip select pin (active low)
wim 15:b70ebfffb258 82 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 15:b70ebfffb258 83 */
wim 14:0c32b66b14b8 84 TextLCD::TextLCD(SPI *spi, PinName cs, LCDType type) :
wim 15:b70ebfffb258 85 _rs(NC), _e(NC), _e2(NC),
wim 15:b70ebfffb258 86 _d(NC),
wim 15:b70ebfffb258 87 _spi(spi),
wim 15:b70ebfffb258 88 _cs(cs),
wim 14:0c32b66b14b8 89 _type(type) {
wim 14:0c32b66b14b8 90
wim 14:0c32b66b14b8 91 _busType = _SPIBus;
wim 14:0c32b66b14b8 92
wim 14:0c32b66b14b8 93 // Setup the spi for 8 bit data, low steady state clock,
wim 14:0c32b66b14b8 94 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 14:0c32b66b14b8 95 _spi->format(8,0);
wim 14:0c32b66b14b8 96 _spi->frequency(500000);
wim 14:0c32b66b14b8 97 //_spi.frequency(1000000);
wim 14:0c32b66b14b8 98
wim 14:0c32b66b14b8 99
wim 14:0c32b66b14b8 100 // Init the portexpander bus
wim 15:b70ebfffb258 101 _lcd_bus = D_LCD_BUS_DEF;
wim 14:0c32b66b14b8 102
wim 14:0c32b66b14b8 103 // write the new data to the portexpander
wim 14:0c32b66b14b8 104 _setCS(false);
wim 14:0c32b66b14b8 105 _spi->write(_lcd_bus);
wim 14:0c32b66b14b8 106 _setCS(true);
wim 14:0c32b66b14b8 107
wim 14:0c32b66b14b8 108 _init();
wim 14:0c32b66b14b8 109
wim 14:0c32b66b14b8 110 }
wim 14:0c32b66b14b8 111
wim 14:0c32b66b14b8 112
wim 15:b70ebfffb258 113 /* Init the LCD Controller(s)
wim 13:24506ba22480 114 * Clear display
wim 13:24506ba22480 115 */
wim 13:24506ba22480 116 void TextLCD::_init() {
wim 15:b70ebfffb258 117
wim 15:b70ebfffb258 118 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 119 if(_type==LCD40x4) {
wim 15:b70ebfffb258 120 _ctrl=TextLCD::_LCDCtrl_1; // Select 2nd controller
wim 15:b70ebfffb258 121
wim 15:b70ebfffb258 122 _initCtrl(); // Init 2nd controller
wim 15:b70ebfffb258 123
wim 15:b70ebfffb258 124 // Secondary LCD controller Clearscreen
wim 15:b70ebfffb258 125 _writeCommand(0x01); // cls, and set cursor to 0
wim 15:b70ebfffb258 126 wait_ms(10); // The CLS command takes 1.64 ms.
wim 15:b70ebfffb258 127 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 15:b70ebfffb258 128
wim 15:b70ebfffb258 129 }
wim 15:b70ebfffb258 130
wim 15:b70ebfffb258 131 // Select and configure primary LCD controller
wim 15:b70ebfffb258 132 _ctrl=TextLCD::_LCDCtrl_0; // Select primary controller
wim 13:24506ba22480 133
wim 15:b70ebfffb258 134 _initCtrl(); // Init primary controller
wim 15:b70ebfffb258 135
wim 15:b70ebfffb258 136 // Primary LCD controller Clearscreen
wim 15:b70ebfffb258 137 _writeCommand(0x01); // cls, and set cursor to 0
wim 15:b70ebfffb258 138
wim 15:b70ebfffb258 139 wait_ms(10); // The CLS command takes 1.64 ms.
wim 15:b70ebfffb258 140 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 15:b70ebfffb258 141
wim 15:b70ebfffb258 142 }
wim 15:b70ebfffb258 143
wim 15:b70ebfffb258 144 /* Init the LCD controller
wim 15:b70ebfffb258 145 * 4-bit mode, number of lines, fonttype, no cursor etc
wim 15:b70ebfffb258 146 *
wim 15:b70ebfffb258 147 */
wim 15:b70ebfffb258 148 void TextLCD::_initCtrl() {
wim 15:b70ebfffb258 149
wim 13:24506ba22480 150 _setRS(false); // command mode
wim 13:24506ba22480 151
wim 15:b70ebfffb258 152 wait_ms(20); // Wait 20ms to ensure powered up
simon 1:ac48b187213c 153
simon 1:ac48b187213c 154 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
simon 1:ac48b187213c 155 for (int i=0; i<3; i++) {
wim 13:24506ba22480 156 _writeByte(0x3);
wim 15:b70ebfffb258 157 wait_ms(15); // this command takes 1.64ms, so wait for it
simon 1:ac48b187213c 158 }
wim 13:24506ba22480 159 _writeByte(0x2); // 4-bit mode
wim 14:0c32b66b14b8 160 wait_us(40); // most instructions take 40us
wim 14:0c32b66b14b8 161
wim 10:dd9b3a696acd 162 // Display is now in 4-bit mode
wim 10:dd9b3a696acd 163 switch (_type) {
wim 10:dd9b3a696acd 164 case LCD8x1:
wim 15:b70ebfffb258 165 _writeCommand(0x20); // Function set 001 DL N F - -
wim 15:b70ebfffb258 166 // DL=0 (4 bits bus)
wim 13:24506ba22480 167 // N=0 (1 line)
wim 13:24506ba22480 168 // F=0 (5x7 dots font)
wim 10:dd9b3a696acd 169 break;
wim 10:dd9b3a696acd 170
wim 10:dd9b3a696acd 171 case LCD24x4:
wim 10:dd9b3a696acd 172 // Special mode for KS0078
wim 15:b70ebfffb258 173 _writeCommand(0x2A); // Function set 001 DL N RE DH REV
wim 15:b70ebfffb258 174 // DL=0 (4 bits bus)
wim 13:24506ba22480 175 // N=1 (Dont care for KS0078)
wim 13:24506ba22480 176 // RE=0 (Extended Regs, special mode for KS0078)
wim 13:24506ba22480 177 // DH=1 (Disp shift, special mode for KS0078)
wim 13:24506ba22480 178 // REV=0 (Reverse, special mode for KS0078)
wim 10:dd9b3a696acd 179
wim 15:b70ebfffb258 180 _writeCommand(0x2E); // Function set 001 DL N RE DH REV
wim 15:b70ebfffb258 181 // DL=0 (4 bits bus)
wim 13:24506ba22480 182 // N=1 (Dont care for KS0078)
wim 13:24506ba22480 183 // RE=1 (Ena Extended Regs, special mode for KS0078)
wim 13:24506ba22480 184 // DH=1 (Disp shift, special mode for KS0078)
wim 13:24506ba22480 185 // REV=0 (Reverse, special mode for KS0078)
wim 10:dd9b3a696acd 186
wim 13:24506ba22480 187 _writeCommand(0x09); // Ext Function set 0000 1 FW BW NW
wim 13:24506ba22480 188 // FW=0 (5-dot font, special mode for KS0078)
wim 13:24506ba22480 189 // BW=0 (Cur BW invert disable, special mode for KS0078)
wim 13:24506ba22480 190 // NW=1 (4 Line, special mode for KS0078)
wim 10:dd9b3a696acd 191
wim 15:b70ebfffb258 192 _writeCommand(0x2A); // Function set 001 DL N RE DH REV
wim 15:b70ebfffb258 193 // DL=0 (4 bits bus)
wim 13:24506ba22480 194 // N=1 (Dont care for KS0078)
wim 13:24506ba22480 195 // RE=0 (Dis. Extended Regs, special mode for KS0078)
wim 13:24506ba22480 196 // DH=1 (Disp shift, special mode for KS0078)
wim 13:24506ba22480 197 // REV=0 (Reverse, special mode for KS0078)
wim 10:dd9b3a696acd 198 break;
wim 10:dd9b3a696acd 199
wim 15:b70ebfffb258 200 // All other LCD types are initialised as 2 Line displays (including LCD40x4)
wim 10:dd9b3a696acd 201 default:
wim 15:b70ebfffb258 202 _writeCommand(0x28); // Function set 001 DL N F - -
wim 15:b70ebfffb258 203 // DL=0 (4 bits bus)
wim 13:24506ba22480 204 // N=1 (2 lines)
wim 15:b70ebfffb258 205 // F=0 (5x7 dots font, only option for 2 line display)
wim 13:24506ba22480 206 // - (Don't care)
wim 10:dd9b3a696acd 207
wim 10:dd9b3a696acd 208 break;
wim 10:dd9b3a696acd 209 }
wim 10:dd9b3a696acd 210
wim 13:24506ba22480 211 _writeCommand(0x06); // Entry Mode 0000 01 CD S
wim 13:24506ba22480 212 // Cursor Direction and Display Shift
wim 13:24506ba22480 213 // CD=1 (Cur incr)
wim 13:24506ba22480 214 // S=0 (No display shift)
wim 10:dd9b3a696acd 215
wim 13:24506ba22480 216 // _writeCommand(0x0C); // Display Ctrl 0000 1 D C B
wim 13:24506ba22480 217 // // Display On, Cursor Off, Blink Off
wim 15:b70ebfffb258 218 setCursor(TextLCD::CurOff_BlkOff);
wim 15:b70ebfffb258 219
simon 1:ac48b187213c 220 }
simon 1:ac48b187213c 221
wim 8:03116f75b66e 222
wim 15:b70ebfffb258 223
wim 15:b70ebfffb258 224 #if(LCD40x4Test)
wim 15:b70ebfffb258 225 void TextLCD::cls() {
wim 15:b70ebfffb258 226
wim 15:b70ebfffb258 227 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 228 if(_type==LCD40x4) {
wim 15:b70ebfffb258 229 _ctrl=TextLCD::_LCDCtrl_1; // Select 2nd controller
wim 15:b70ebfffb258 230
wim 15:b70ebfffb258 231 // Second LCD controller Cursor always Off
wim 15:b70ebfffb258 232 _setCursor(TextLCD::CurOff_BlkOff);
wim 15:b70ebfffb258 233
wim 15:b70ebfffb258 234 // Second LCD controller Clearscreen
wim 15:b70ebfffb258 235 _writeCommand(0x01); // cls, and set cursor to 0
wim 15:b70ebfffb258 236
wim 15:b70ebfffb258 237 wait_ms(10); // The CLS command takes 1.64 ms.
wim 15:b70ebfffb258 238 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 15:b70ebfffb258 239
wim 15:b70ebfffb258 240
wim 15:b70ebfffb258 241 _ctrl=TextLCD::_LCDCtrl_0; // Select primary controller
wim 15:b70ebfffb258 242 }
wim 15:b70ebfffb258 243
wim 15:b70ebfffb258 244 // Primary LCD controller Clearscreen
wim 15:b70ebfffb258 245 _writeCommand(0x01); // cls, and set cursor to 0
wim 15:b70ebfffb258 246
wim 15:b70ebfffb258 247 wait_ms(10); // The CLS command takes 1.64 ms.
wim 15:b70ebfffb258 248 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 15:b70ebfffb258 249
wim 15:b70ebfffb258 250 // Restore cursormode on primary LCD controller when needed
wim 15:b70ebfffb258 251 if(_type==LCD40x4) {
wim 15:b70ebfffb258 252 _setCursor(_currentCursor);
wim 15:b70ebfffb258 253 }
wim 15:b70ebfffb258 254
wim 15:b70ebfffb258 255 _row=0; // Reset Cursor location
wim 15:b70ebfffb258 256 _column=0;
simon 1:ac48b187213c 257 }
simon 1:ac48b187213c 258
wim 15:b70ebfffb258 259 #else
wim 15:b70ebfffb258 260 //standard
simon 1:ac48b187213c 261 void TextLCD::cls() {
wim 13:24506ba22480 262 _writeCommand(0x01); // cls, and set cursor to 0
wim 15:b70ebfffb258 263
wim 14:0c32b66b14b8 264 wait_ms(10); // The CLS command takes 1.64 ms.
wim 14:0c32b66b14b8 265 // Since we are not using the Busy flag, Lets be safe and take 10 ms
simon 1:ac48b187213c 266 locate(0, 0);
simon 1:ac48b187213c 267 }
wim 15:b70ebfffb258 268 #endif
simon 1:ac48b187213c 269
simon 1:ac48b187213c 270 void TextLCD::locate(int column, int row) {
wim 15:b70ebfffb258 271
wim 15:b70ebfffb258 272 // setAddress() does all the heavy lifting:
wim 15:b70ebfffb258 273 // check column and row sanity,
wim 15:b70ebfffb258 274 // switch controllers for LCD40x4 if needed
wim 15:b70ebfffb258 275 // switch cursor for LCD40x4 if needed
wim 15:b70ebfffb258 276 // set the new memory address to show cursor at correct location
wim 15:b70ebfffb258 277 setAddress(column, row);
wim 15:b70ebfffb258 278
wim 15:b70ebfffb258 279 }
wim 15:b70ebfffb258 280
wim 15:b70ebfffb258 281
wim 15:b70ebfffb258 282 //Not needed in new version, is now part of _putc()
wim 15:b70ebfffb258 283 void TextLCD::_character(int column, int row, int c) {
wim 15:b70ebfffb258 284 int addr = getAddress(column, row);
wim 15:b70ebfffb258 285
wim 15:b70ebfffb258 286 _writeCommand(0x80 | addr);
wim 15:b70ebfffb258 287 _writeData(c);
simon 1:ac48b187213c 288 }
simon 1:ac48b187213c 289
wim 15:b70ebfffb258 290
wim 15:b70ebfffb258 291 #if(LCD40x4Test)
wim 15:b70ebfffb258 292
wim 15:b70ebfffb258 293 int TextLCD::_putc(int value) {
wim 15:b70ebfffb258 294 int addr;
wim 15:b70ebfffb258 295
wim 15:b70ebfffb258 296 if (value == '\n') {
wim 15:b70ebfffb258 297 //No character to write
wim 15:b70ebfffb258 298
wim 15:b70ebfffb258 299 //Update Cursor
wim 15:b70ebfffb258 300 _column = 0;
wim 15:b70ebfffb258 301 _row++;
wim 15:b70ebfffb258 302 if (_row >= rows()) {
wim 15:b70ebfffb258 303 _row = 0;
wim 15:b70ebfffb258 304 }
wim 15:b70ebfffb258 305 }
wim 15:b70ebfffb258 306 else {
wim 15:b70ebfffb258 307 //Character to write
wim 15:b70ebfffb258 308 _writeData(value);
wim 15:b70ebfffb258 309
wim 15:b70ebfffb258 310 //Update Cursor
wim 15:b70ebfffb258 311 _column++;
wim 15:b70ebfffb258 312 if (_column >= columns()) {
wim 15:b70ebfffb258 313 _column = 0;
wim 15:b70ebfffb258 314 _row++;
wim 15:b70ebfffb258 315 if (_row >= rows()) {
wim 15:b70ebfffb258 316 _row = 0;
wim 15:b70ebfffb258 317 }
wim 15:b70ebfffb258 318 }
wim 15:b70ebfffb258 319 } //else
wim 15:b70ebfffb258 320
wim 15:b70ebfffb258 321 //Set next memoryaddress, make sure cursor blinks at next location
wim 15:b70ebfffb258 322 addr = getAddress(_column, _row);
wim 15:b70ebfffb258 323 _writeCommand(0x80 | addr);
wim 15:b70ebfffb258 324
wim 15:b70ebfffb258 325 return value;
wim 15:b70ebfffb258 326 }
wim 15:b70ebfffb258 327 #else
wim 15:b70ebfffb258 328 //Standard
simon 1:ac48b187213c 329 int TextLCD::_putc(int value) {
simon 1:ac48b187213c 330 if (value == '\n') {
simon 1:ac48b187213c 331 _column = 0;
simon 1:ac48b187213c 332 _row++;
simon 1:ac48b187213c 333 if (_row >= rows()) {
simon 1:ac48b187213c 334 _row = 0;
simon 1:ac48b187213c 335 }
simon 1:ac48b187213c 336 } else {
wim 13:24506ba22480 337 _character(_column, _row, value);
simon 1:ac48b187213c 338 _column++;
simon 1:ac48b187213c 339 if (_column >= columns()) {
simon 1:ac48b187213c 340 _column = 0;
simon 1:ac48b187213c 341 _row++;
simon 1:ac48b187213c 342 if (_row >= rows()) {
simon 1:ac48b187213c 343 _row = 0;
simon 1:ac48b187213c 344 }
simon 1:ac48b187213c 345 }
simon 1:ac48b187213c 346 }
wim 15:b70ebfffb258 347
simon 1:ac48b187213c 348 return value;
simon 1:ac48b187213c 349 }
simon 1:ac48b187213c 350
wim 15:b70ebfffb258 351 #endif
wim 15:b70ebfffb258 352
wim 15:b70ebfffb258 353
wim 15:b70ebfffb258 354
wim 15:b70ebfffb258 355
wim 15:b70ebfffb258 356
simon 1:ac48b187213c 357 int TextLCD::_getc() {
simon 1:ac48b187213c 358 return -1;
simon 1:ac48b187213c 359 }
simon 1:ac48b187213c 360
wim 13:24506ba22480 361
wim 13:24506ba22480 362 void TextLCD::_setEnable(bool value) {
wim 13:24506ba22480 363
wim 13:24506ba22480 364 switch(_busType) {
wim 13:24506ba22480 365 case _PinBus :
wim 15:b70ebfffb258 366 #if(LCD40x4Test)
wim 15:b70ebfffb258 367 if(_ctrl==TextLCD::_LCDCtrl_0) {
wim 15:b70ebfffb258 368 if (value)
wim 15:b70ebfffb258 369 _e = 1; // Set E bit
wim 15:b70ebfffb258 370 else
wim 15:b70ebfffb258 371 _e = 0; // Reset E bit
wim 15:b70ebfffb258 372 }
wim 15:b70ebfffb258 373 else {
wim 15:b70ebfffb258 374 if (value)
wim 15:b70ebfffb258 375 _e2 = 1; // Set E2 bit
wim 15:b70ebfffb258 376 else
wim 15:b70ebfffb258 377 _e2 = 0; // Reset E2 bit
wim 15:b70ebfffb258 378 }
wim 15:b70ebfffb258 379
wim 15:b70ebfffb258 380 #else
wim 13:24506ba22480 381 if (value)
wim 13:24506ba22480 382 _e = 1; // Set E bit
wim 13:24506ba22480 383 else
wim 13:24506ba22480 384 _e = 0; // Reset E bit
wim 15:b70ebfffb258 385 #endif
wim 13:24506ba22480 386 break;
wim 13:24506ba22480 387
wim 13:24506ba22480 388 case _I2CBus :
wim 15:b70ebfffb258 389
wim 15:b70ebfffb258 390 #if(LCD40x4Test)
wim 15:b70ebfffb258 391 if(_ctrl==TextLCD::_LCDCtrl_0) {
wim 15:b70ebfffb258 392 if (value)
wim 15:b70ebfffb258 393 _lcd_bus |= D_LCD_E; // Set E bit
wim 15:b70ebfffb258 394 else
wim 15:b70ebfffb258 395 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 15:b70ebfffb258 396 }
wim 15:b70ebfffb258 397 else {
wim 15:b70ebfffb258 398 if (value)
wim 15:b70ebfffb258 399 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 15:b70ebfffb258 400 else
wim 15:b70ebfffb258 401 _lcd_bus &= ~D_LCD_E2; // Reset E2bit
wim 15:b70ebfffb258 402 }
wim 15:b70ebfffb258 403
wim 15:b70ebfffb258 404 #else
wim 14:0c32b66b14b8 405 if (value)
wim 14:0c32b66b14b8 406 _lcd_bus |= D_LCD_E; // Set E bit
wim 14:0c32b66b14b8 407 else
wim 14:0c32b66b14b8 408 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 13:24506ba22480 409
wim 15:b70ebfffb258 410 #endif
wim 15:b70ebfffb258 411 // write the new data to the I2C portexpander
wim 14:0c32b66b14b8 412 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 15:b70ebfffb258 413
wim 13:24506ba22480 414 break;
wim 13:24506ba22480 415
wim 13:24506ba22480 416 case _SPIBus :
wim 15:b70ebfffb258 417 #if(LCD40x4Test)
wim 15:b70ebfffb258 418 if(_ctrl==TextLCD::_LCDCtrl_0) {
wim 15:b70ebfffb258 419 if (value)
wim 15:b70ebfffb258 420 _lcd_bus |= D_LCD_E; // Set E bit
wim 15:b70ebfffb258 421 else
wim 15:b70ebfffb258 422 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 15:b70ebfffb258 423 }
wim 15:b70ebfffb258 424 else {
wim 15:b70ebfffb258 425 if (value)
wim 15:b70ebfffb258 426 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 15:b70ebfffb258 427 else
wim 15:b70ebfffb258 428 _lcd_bus &= ~D_LCD_E2; // Reset E2 bit
wim 15:b70ebfffb258 429 }
wim 15:b70ebfffb258 430
wim 15:b70ebfffb258 431 #else
wim 14:0c32b66b14b8 432 if (value)
wim 14:0c32b66b14b8 433 _lcd_bus |= D_LCD_E; // Set E bit
wim 14:0c32b66b14b8 434 else
wim 14:0c32b66b14b8 435 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 15:b70ebfffb258 436 #endif
wim 15:b70ebfffb258 437
wim 15:b70ebfffb258 438 // write the new data to the SPI portexpander
wim 14:0c32b66b14b8 439 _setCS(false);
wim 14:0c32b66b14b8 440 _spi->write(_lcd_bus);
wim 14:0c32b66b14b8 441 _setCS(true);
wim 14:0c32b66b14b8 442
wim 13:24506ba22480 443 break;
wim 13:24506ba22480 444 }
wim 13:24506ba22480 445 }
wim 13:24506ba22480 446
wim 13:24506ba22480 447 void TextLCD::_setRS(bool value) {
wim 13:24506ba22480 448
wim 13:24506ba22480 449 switch(_busType) {
wim 13:24506ba22480 450 case _PinBus :
wim 13:24506ba22480 451 if (value)
wim 13:24506ba22480 452 _rs = 1; // Set RS bit
wim 13:24506ba22480 453 else
wim 13:24506ba22480 454 _rs = 0; // Reset RS bit
wim 13:24506ba22480 455
wim 13:24506ba22480 456 break;
wim 13:24506ba22480 457
wim 13:24506ba22480 458 case _I2CBus :
wim 14:0c32b66b14b8 459 if (value)
wim 14:0c32b66b14b8 460 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 14:0c32b66b14b8 461 else
wim 14:0c32b66b14b8 462 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 13:24506ba22480 463
wim 15:b70ebfffb258 464 // write the new data to the I2C portexpander
wim 14:0c32b66b14b8 465 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 13:24506ba22480 466
wim 13:24506ba22480 467 break;
wim 13:24506ba22480 468
wim 13:24506ba22480 469 case _SPIBus :
wim 14:0c32b66b14b8 470 if (value)
wim 14:0c32b66b14b8 471 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 14:0c32b66b14b8 472 else
wim 14:0c32b66b14b8 473 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 14:0c32b66b14b8 474
wim 15:b70ebfffb258 475 // write the new data to the SPI portexpander
wim 14:0c32b66b14b8 476 _setCS(false);
wim 14:0c32b66b14b8 477 _spi->write(_lcd_bus);
wim 14:0c32b66b14b8 478 _setCS(true);
wim 14:0c32b66b14b8 479
wim 13:24506ba22480 480 break;
wim 13:24506ba22480 481 }
wim 13:24506ba22480 482
wim 13:24506ba22480 483 }
wim 13:24506ba22480 484
wim 13:24506ba22480 485 void TextLCD::_setData(int value) {
wim 13:24506ba22480 486 int data;
wim 13:24506ba22480 487
wim 13:24506ba22480 488 switch(_busType) {
wim 13:24506ba22480 489 case _PinBus :
wim 13:24506ba22480 490 _d = value & 0x0F; // Write Databits
wim 13:24506ba22480 491
wim 13:24506ba22480 492 break;
wim 13:24506ba22480 493
wim 13:24506ba22480 494 case _I2CBus :
wim 13:24506ba22480 495 data = value & 0x0F;
wim 13:24506ba22480 496 if (data & 0x01)
wim 13:24506ba22480 497 _lcd_bus |= D_LCD_D4; // Set Databit
wim 13:24506ba22480 498 else
wim 13:24506ba22480 499 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 13:24506ba22480 500
wim 13:24506ba22480 501 if (data & 0x02)
wim 13:24506ba22480 502 _lcd_bus |= D_LCD_D5; // Set Databit
wim 13:24506ba22480 503 else
wim 13:24506ba22480 504 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 13:24506ba22480 505
wim 13:24506ba22480 506 if (data & 0x04)
wim 13:24506ba22480 507 _lcd_bus |= D_LCD_D6; // Set Databit
wim 13:24506ba22480 508 else
wim 13:24506ba22480 509 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 13:24506ba22480 510
wim 13:24506ba22480 511 if (data & 0x08)
wim 13:24506ba22480 512 _lcd_bus |= D_LCD_D7; // Set Databit
wim 13:24506ba22480 513 else
wim 13:24506ba22480 514 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 13:24506ba22480 515
wim 15:b70ebfffb258 516 // write the new data to the I2C portexpander
wim 13:24506ba22480 517 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 13:24506ba22480 518
wim 13:24506ba22480 519 break;
wim 13:24506ba22480 520
wim 13:24506ba22480 521 case _SPIBus :
wim 14:0c32b66b14b8 522
wim 14:0c32b66b14b8 523 data = value & 0x0F;
wim 14:0c32b66b14b8 524 if (data & 0x01)
wim 14:0c32b66b14b8 525 _lcd_bus |= D_LCD_D4; // Set Databit
wim 14:0c32b66b14b8 526 else
wim 14:0c32b66b14b8 527 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 14:0c32b66b14b8 528
wim 14:0c32b66b14b8 529 if (data & 0x02)
wim 14:0c32b66b14b8 530 _lcd_bus |= D_LCD_D5; // Set Databit
wim 14:0c32b66b14b8 531 else
wim 14:0c32b66b14b8 532 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 14:0c32b66b14b8 533
wim 14:0c32b66b14b8 534 if (data & 0x04)
wim 14:0c32b66b14b8 535 _lcd_bus |= D_LCD_D6; // Set Databit
wim 14:0c32b66b14b8 536 else
wim 14:0c32b66b14b8 537 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 14:0c32b66b14b8 538
wim 14:0c32b66b14b8 539 if (data & 0x08)
wim 14:0c32b66b14b8 540 _lcd_bus |= D_LCD_D7; // Set Databit
wim 14:0c32b66b14b8 541 else
wim 14:0c32b66b14b8 542 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 14:0c32b66b14b8 543
wim 15:b70ebfffb258 544 // write the new data to the SPI portexpander
wim 14:0c32b66b14b8 545 _setCS(false);
wim 14:0c32b66b14b8 546 _spi->write(_lcd_bus);
wim 14:0c32b66b14b8 547 _setCS(true);
wim 14:0c32b66b14b8 548
wim 14:0c32b66b14b8 549 break;
wim 13:24506ba22480 550 }
wim 13:24506ba22480 551
wim 13:24506ba22480 552 }
wim 13:24506ba22480 553
wim 13:24506ba22480 554
wim 14:0c32b66b14b8 555 // Set CS line. Only used for SPI bus
wim 14:0c32b66b14b8 556 void TextLCD::_setCS(bool value) {
wim 14:0c32b66b14b8 557
wim 15:b70ebfffb258 558 if (value) {
wim 14:0c32b66b14b8 559 _cs = 1; // Set CS pin
wim 15:b70ebfffb258 560 }
wim 14:0c32b66b14b8 561 else
wim 14:0c32b66b14b8 562 _cs = 0; // Reset CS pin
wim 15:b70ebfffb258 563
wim 14:0c32b66b14b8 564 }
wim 14:0c32b66b14b8 565
wim 14:0c32b66b14b8 566
wim 13:24506ba22480 567
wim 13:24506ba22480 568 void TextLCD::_writeByte(int value) {
wim 15:b70ebfffb258 569
wim 15:b70ebfffb258 570 // Enable is Low
wim 15:b70ebfffb258 571 _setEnable(true);
wim 15:b70ebfffb258 572 _setData(value >> 4);
wim 15:b70ebfffb258 573 wait_us(1); // Data setup time
wim 15:b70ebfffb258 574 _setEnable(false);
wim 15:b70ebfffb258 575 wait_us(1); // Data hold time
wim 15:b70ebfffb258 576
wim 13:24506ba22480 577 _setEnable(true);
wim 13:24506ba22480 578 _setData(value >> 0);
wim 15:b70ebfffb258 579 wait_us(1); // Data setup time
wim 13:24506ba22480 580 _setEnable(false);
wim 15:b70ebfffb258 581 wait_us(1); // Datahold time
wim 15:b70ebfffb258 582
wim 15:b70ebfffb258 583 // Enable is Low
wim 15:b70ebfffb258 584
simon 1:ac48b187213c 585 }
simon 1:ac48b187213c 586
wim 13:24506ba22480 587 void TextLCD::_writeCommand(int command) {
wim 15:b70ebfffb258 588
wim 13:24506ba22480 589 _setRS(false);
wim 15:b70ebfffb258 590 wait_us(1); // Data setup time
wim 15:b70ebfffb258 591
wim 15:b70ebfffb258 592 _writeByte(command);
wim 15:b70ebfffb258 593 wait_us(40); // most instructions take 40us
simon 1:ac48b187213c 594 }
simon 1:ac48b187213c 595
wim 13:24506ba22480 596 void TextLCD::_writeData(int data) {
wim 15:b70ebfffb258 597
wim 13:24506ba22480 598 _setRS(true);
wim 15:b70ebfffb258 599 wait_us(1); // Data setup time
wim 15:b70ebfffb258 600
wim 13:24506ba22480 601 _writeByte(data);
wim 15:b70ebfffb258 602 wait_us(40); // data writes take 40us
simon 1:ac48b187213c 603 }
simon 1:ac48b187213c 604
wim 8:03116f75b66e 605
wim 8:03116f75b66e 606 #if (0)
wim 8:03116f75b66e 607 // This is the original method.
wim 8:03116f75b66e 608 // It is confusing since it returns the memoryaddress or-ed with the set memorycommand 0x80.
wim 8:03116f75b66e 609 // Left it in here for compatibility with older code. New applications should use getAddress() instead.
wim 8:03116f75b66e 610 //
wim 13:24506ba22480 611 int TextLCD::_address(int column, int row) {
simon 1:ac48b187213c 612 switch (_type) {
simon 1:ac48b187213c 613 case LCD20x4:
simon 1:ac48b187213c 614 switch (row) {
simon 1:ac48b187213c 615 case 0:
simon 1:ac48b187213c 616 return 0x80 + column;
simon 1:ac48b187213c 617 case 1:
simon 1:ac48b187213c 618 return 0xc0 + column;
simon 1:ac48b187213c 619 case 2:
simon 1:ac48b187213c 620 return 0x94 + column;
simon 1:ac48b187213c 621 case 3:
simon 1:ac48b187213c 622 return 0xd4 + column;
simon 1:ac48b187213c 623 }
simon 1:ac48b187213c 624 case LCD16x2B:
simon 4:bf5b706f8d32 625 return 0x80 + (row * 40) + column;
simon 1:ac48b187213c 626 case LCD16x2:
simon 1:ac48b187213c 627 case LCD20x2:
simon 1:ac48b187213c 628 default:
simon 4:bf5b706f8d32 629 return 0x80 + (row * 0x40) + column;
simon 1:ac48b187213c 630 }
simon 1:ac48b187213c 631 }
wim 8:03116f75b66e 632 #endif
wim 8:03116f75b66e 633
wim 8:03116f75b66e 634
wim 8:03116f75b66e 635 // This replaces the original method.
wim 8:03116f75b66e 636 // Left it in here for compatibility with older code. New applications should use getAddress() instead.
wim 13:24506ba22480 637 int TextLCD::_address(int column, int row) {
wim 8:03116f75b66e 638 return 0x80 | getAddress(column, row);
wim 8:03116f75b66e 639 }
wim 8:03116f75b66e 640
wim 8:03116f75b66e 641 // This is new method to return the memory address based on row, column and displaytype.
wim 8:03116f75b66e 642 //
wim 8:03116f75b66e 643 int TextLCD::getAddress(int column, int row) {
wim 8:03116f75b66e 644
wim 8:03116f75b66e 645 switch (_type) {
wim 8:03116f75b66e 646 case LCD8x1:
wim 8:03116f75b66e 647 return 0x00 + column;
wim 8:03116f75b66e 648
wim 13:24506ba22480 649 case LCD16x1:
wim 13:24506ba22480 650 // LCD16x1 is a special layout of LCD8x2
wim 13:24506ba22480 651 if (column<8)
wim 13:24506ba22480 652 return 0x00 + column;
wim 13:24506ba22480 653 else
wim 13:24506ba22480 654 return 0x40 + (column - 8);
wim 13:24506ba22480 655
wim 15:b70ebfffb258 656 case LCD12x4:
wim 15:b70ebfffb258 657 switch (row) {
wim 15:b70ebfffb258 658 case 0:
wim 15:b70ebfffb258 659 return 0x00 + column;
wim 15:b70ebfffb258 660 case 1:
wim 15:b70ebfffb258 661 return 0x40 + column;
wim 15:b70ebfffb258 662 case 2:
wim 15:b70ebfffb258 663 return 0x0C + column;
wim 15:b70ebfffb258 664 case 3:
wim 15:b70ebfffb258 665 return 0x4C + column;
wim 15:b70ebfffb258 666 }
wim 15:b70ebfffb258 667
wim 8:03116f75b66e 668 case LCD16x4:
wim 8:03116f75b66e 669 switch (row) {
wim 8:03116f75b66e 670 case 0:
wim 8:03116f75b66e 671 return 0x00 + column;
wim 8:03116f75b66e 672 case 1:
wim 8:03116f75b66e 673 return 0x40 + column;
wim 8:03116f75b66e 674 case 2:
wim 8:03116f75b66e 675 return 0x10 + column;
wim 8:03116f75b66e 676 case 3:
wim 8:03116f75b66e 677 return 0x50 + column;
wim 8:03116f75b66e 678 }
wim 8:03116f75b66e 679
wim 8:03116f75b66e 680 case LCD20x4:
wim 8:03116f75b66e 681 switch (row) {
wim 8:03116f75b66e 682 case 0:
wim 8:03116f75b66e 683 return 0x00 + column;
wim 8:03116f75b66e 684 case 1:
wim 8:03116f75b66e 685 return 0x40 + column;
wim 8:03116f75b66e 686 case 2:
wim 8:03116f75b66e 687 return 0x14 + column;
wim 8:03116f75b66e 688 case 3:
wim 8:03116f75b66e 689 return 0x54 + column;
wim 8:03116f75b66e 690 }
wim 8:03116f75b66e 691
wim 10:dd9b3a696acd 692 // Special mode for KS0078
wim 10:dd9b3a696acd 693 case LCD24x4:
wim 10:dd9b3a696acd 694 switch (row) {
wim 10:dd9b3a696acd 695 case 0:
wim 10:dd9b3a696acd 696 return 0x00 + column;
wim 10:dd9b3a696acd 697 case 1:
wim 10:dd9b3a696acd 698 return 0x20 + column;
wim 10:dd9b3a696acd 699 case 2:
wim 10:dd9b3a696acd 700 return 0x40 + column;
wim 10:dd9b3a696acd 701 case 3:
wim 10:dd9b3a696acd 702 return 0x60 + column;
wim 10:dd9b3a696acd 703 }
wim 10:dd9b3a696acd 704
wim 8:03116f75b66e 705 // Not sure about this one, seems wrong.
wim 8:03116f75b66e 706 case LCD16x2B:
wim 8:03116f75b66e 707 return 0x00 + (row * 40) + column;
wim 8:03116f75b66e 708
wim 8:03116f75b66e 709 case LCD8x2:
wim 15:b70ebfffb258 710 case LCD12x2:
wim 8:03116f75b66e 711 case LCD16x2:
wim 8:03116f75b66e 712 case LCD20x2:
wim 8:03116f75b66e 713 case LCD24x2:
wim 9:0893d986e717 714 case LCD40x2:
wim 8:03116f75b66e 715 return 0x00 + (row * 0x40) + column;
wim 15:b70ebfffb258 716
wim 15:b70ebfffb258 717 #if(LCD40x4Test)
wim 15:b70ebfffb258 718 case LCD40x4:
wim 15:b70ebfffb258 719 // LCD40x4 is a special case since it has 2 controllers
wim 15:b70ebfffb258 720 // Each controller is configured as 40x2
wim 15:b70ebfffb258 721 if (row<2) {
wim 15:b70ebfffb258 722 // Test to see if we need to switch between controllers
wim 15:b70ebfffb258 723 if (_ctrl != _LCDCtrl_0) {
wim 15:b70ebfffb258 724 // Second LCD controller Cursor Off
wim 15:b70ebfffb258 725 _setCursor(TextLCD::CurOff_BlkOff);
wim 15:b70ebfffb258 726
wim 15:b70ebfffb258 727 // Select primary controller
wim 15:b70ebfffb258 728 _ctrl = _LCDCtrl_0;
wim 15:b70ebfffb258 729
wim 15:b70ebfffb258 730 // Restore cursormode on primary LCD controller
wim 15:b70ebfffb258 731 _setCursor(_currentCursor);
wim 15:b70ebfffb258 732 }
wim 15:b70ebfffb258 733
wim 15:b70ebfffb258 734 return 0x00 + (row * 0x40) + column;
wim 15:b70ebfffb258 735 }
wim 15:b70ebfffb258 736 else {
wim 15:b70ebfffb258 737
wim 15:b70ebfffb258 738 // Test to see if we need to switch between controllers
wim 15:b70ebfffb258 739 if (_ctrl != _LCDCtrl_1) {
wim 15:b70ebfffb258 740 // Primary LCD controller Cursor Off
wim 15:b70ebfffb258 741 _setCursor(TextLCD::CurOff_BlkOff);
wim 15:b70ebfffb258 742
wim 15:b70ebfffb258 743 // Select secondary controller
wim 15:b70ebfffb258 744 _ctrl = _LCDCtrl_1;
wim 15:b70ebfffb258 745
wim 15:b70ebfffb258 746 // Restore cursormode on secondary LCD controller
wim 15:b70ebfffb258 747 _setCursor(_currentCursor);
wim 15:b70ebfffb258 748 }
wim 15:b70ebfffb258 749
wim 15:b70ebfffb258 750 return 0x00 + ((row-2) * 0x40) + column;
wim 15:b70ebfffb258 751 }
wim 15:b70ebfffb258 752
wim 15:b70ebfffb258 753 #endif
wim 8:03116f75b66e 754
wim 8:03116f75b66e 755 // Should never get here.
wim 8:03116f75b66e 756 default:
wim 8:03116f75b66e 757 return 0x00;
wim 8:03116f75b66e 758 }
wim 8:03116f75b66e 759 }
wim 8:03116f75b66e 760
wim 8:03116f75b66e 761
wim 15:b70ebfffb258 762 // Set row, column and update memoryaddress.
wim 8:03116f75b66e 763 //
wim 8:03116f75b66e 764 void TextLCD::setAddress(int column, int row) {
wim 15:b70ebfffb258 765
wim 15:b70ebfffb258 766 // Sanity Check column
wim 15:b70ebfffb258 767 if (column < 0) {
wim 15:b70ebfffb258 768 _column = 0;
wim 15:b70ebfffb258 769 }
wim 15:b70ebfffb258 770 else if (column >= columns()) {
wim 15:b70ebfffb258 771 _column = columns() - 1;
wim 15:b70ebfffb258 772 } else _column = column;
wim 8:03116f75b66e 773
wim 15:b70ebfffb258 774 // Sanity Check row
wim 15:b70ebfffb258 775 if (row < 0) {
wim 15:b70ebfffb258 776 _row = 0;
wim 15:b70ebfffb258 777 }
wim 15:b70ebfffb258 778 else if (row >= rows()) {
wim 15:b70ebfffb258 779 _row = rows() - 1;
wim 15:b70ebfffb258 780 } else _row = row;
wim 15:b70ebfffb258 781
wim 15:b70ebfffb258 782
wim 15:b70ebfffb258 783 // Compute the memory address
wim 15:b70ebfffb258 784 // For LCD40x4: switch controllers if needed
wim 15:b70ebfffb258 785 // switch cursor if needed
wim 15:b70ebfffb258 786 int addr = getAddress(_column, _row);
wim 8:03116f75b66e 787
wim 13:24506ba22480 788 _writeCommand(0x80 | addr);
wim 8:03116f75b66e 789 }
simon 1:ac48b187213c 790
simon 1:ac48b187213c 791 int TextLCD::columns() {
simon 1:ac48b187213c 792 switch (_type) {
wim 8:03116f75b66e 793 case LCD8x1:
wim 8:03116f75b66e 794 case LCD8x2:
wim 8:03116f75b66e 795 return 8;
wim 15:b70ebfffb258 796
wim 15:b70ebfffb258 797 case LCD12x2:
wim 15:b70ebfffb258 798 case LCD12x4:
wim 15:b70ebfffb258 799 return 12;
wim 8:03116f75b66e 800
wim 13:24506ba22480 801 case LCD16x1:
simon 1:ac48b187213c 802 case LCD16x2:
simon 1:ac48b187213c 803 case LCD16x2B:
wim 8:03116f75b66e 804 case LCD16x4:
wim 8:03116f75b66e 805 return 16;
wim 8:03116f75b66e 806
wim 8:03116f75b66e 807 case LCD20x2:
wim 8:03116f75b66e 808 case LCD20x4:
wim 8:03116f75b66e 809 return 20;
wim 8:03116f75b66e 810
wim 8:03116f75b66e 811 case LCD24x2:
wim 10:dd9b3a696acd 812 case LCD24x4:
wim 8:03116f75b66e 813 return 24;
wim 9:0893d986e717 814
wim 9:0893d986e717 815 case LCD40x2:
wim 15:b70ebfffb258 816
wim 15:b70ebfffb258 817 #if(LCD40x4Test)
wim 15:b70ebfffb258 818 case LCD40x4:
wim 15:b70ebfffb258 819 #endif
wim 9:0893d986e717 820 return 40;
wim 8:03116f75b66e 821
wim 8:03116f75b66e 822 // Should never get here.
simon 1:ac48b187213c 823 default:
wim 8:03116f75b66e 824 return 0;
simon 1:ac48b187213c 825 }
simon 1:ac48b187213c 826 }
simon 1:ac48b187213c 827
simon 1:ac48b187213c 828 int TextLCD::rows() {
simon 1:ac48b187213c 829 switch (_type) {
wim 8:03116f75b66e 830 case LCD8x1:
wim 13:24506ba22480 831 case LCD16x1:
wim 8:03116f75b66e 832 return 1;
wim 8:03116f75b66e 833
wim 15:b70ebfffb258 834 case LCD8x2:
wim 15:b70ebfffb258 835 case LCD12x2:
simon 1:ac48b187213c 836 case LCD16x2:
simon 1:ac48b187213c 837 case LCD16x2B:
simon 1:ac48b187213c 838 case LCD20x2:
wim 8:03116f75b66e 839 case LCD24x2:
wim 9:0893d986e717 840 case LCD40x2:
wim 8:03116f75b66e 841 return 2;
wim 8:03116f75b66e 842
wim 15:b70ebfffb258 843 case LCD12x4:
wim 8:03116f75b66e 844 case LCD16x4:
wim 8:03116f75b66e 845 case LCD20x4:
wim 10:dd9b3a696acd 846 case LCD24x4:
wim 15:b70ebfffb258 847 #if(LCD40x4Test)
wim 15:b70ebfffb258 848 case LCD40x4:
wim 15:b70ebfffb258 849 #endif
wim 8:03116f75b66e 850 return 4;
wim 12:6bf9d9957d31 851
wim 12:6bf9d9957d31 852 // Should never get here.
simon 1:ac48b187213c 853 default:
wim 8:03116f75b66e 854 return 0;
simon 1:ac48b187213c 855 }
simon 1:ac48b187213c 856 }
wim 10:dd9b3a696acd 857
wim 10:dd9b3a696acd 858
wim 15:b70ebfffb258 859
wim 15:b70ebfffb258 860 #if(LCD40x4Test)
wim 15:b70ebfffb258 861
wim 13:24506ba22480 862 void TextLCD::setCursor(TextLCD::LCDCursor show) {
wim 15:b70ebfffb258 863
wim 15:b70ebfffb258 864 // Save new cursor mode, needed when 2 controllers are in use
wim 15:b70ebfffb258 865 _currentCursor = show;
wim 10:dd9b3a696acd 866
wim 15:b70ebfffb258 867 // Configure current LCD controller
wim 15:b70ebfffb258 868 _setCursor(_currentCursor);
wim 15:b70ebfffb258 869
wim 15:b70ebfffb258 870 }
wim 15:b70ebfffb258 871
wim 15:b70ebfffb258 872 void TextLCD::_setCursor(TextLCD::LCDCursor show) {
wim 15:b70ebfffb258 873
wim 15:b70ebfffb258 874 // Configure current LCD controller
wim 10:dd9b3a696acd 875 switch (show) {
wim 13:24506ba22480 876 case CurOff_BlkOff : _writeCommand(0x0C); // Cursor off and Blink Off
wim 11:9ec02df863a1 877 break;
wim 11:9ec02df863a1 878
wim 15:b70ebfffb258 879 case CurOn_BlkOff : _writeCommand(0x0E); // Cursor on and Blink Off
wim 11:9ec02df863a1 880 break;
wim 11:9ec02df863a1 881
wim 13:24506ba22480 882 case CurOff_BlkOn : _writeCommand(0x0D); // Cursor off and Blink On
wim 11:9ec02df863a1 883 break;
wim 11:9ec02df863a1 884
wim 15:b70ebfffb258 885 case CurOn_BlkOn : _writeCommand(0x0F); // Cursor on and Blink char
wim 11:9ec02df863a1 886 break;
wim 11:9ec02df863a1 887
wim 12:6bf9d9957d31 888 // Should never get here.
wim 10:dd9b3a696acd 889 default :
wim 11:9ec02df863a1 890 break;
wim 10:dd9b3a696acd 891
wim 10:dd9b3a696acd 892 }
wim 11:9ec02df863a1 893
wim 10:dd9b3a696acd 894 }
wim 10:dd9b3a696acd 895
wim 15:b70ebfffb258 896 #else
wim 15:b70ebfffb258 897 //standard
wim 15:b70ebfffb258 898 void TextLCD::setCursor(TextLCD::LCDCursor show) {
wim 15:b70ebfffb258 899
wim 15:b70ebfffb258 900 switch (show) {
wim 15:b70ebfffb258 901 case CurOff_BlkOff : _writeCommand(0x0C); // Cursor off and Blink Off
wim 15:b70ebfffb258 902 break;
wim 10:dd9b3a696acd 903
wim 15:b70ebfffb258 904 case CurOn_BlkOff : _writeCommand(0x0E); // Cursor on and Blink Off
wim 15:b70ebfffb258 905 break;
wim 15:b70ebfffb258 906
wim 15:b70ebfffb258 907 case CurOff_BlkOn : _writeCommand(0x0D); // Cursor off and Blink On
wim 15:b70ebfffb258 908 break;
wim 15:b70ebfffb258 909
wim 15:b70ebfffb258 910 case CurOn_BlkOn : _writeCommand(0x0F); // Cursor on and Blink char
wim 15:b70ebfffb258 911 break;
wim 15:b70ebfffb258 912
wim 15:b70ebfffb258 913 // Should never get here.
wim 15:b70ebfffb258 914 default :
wim 15:b70ebfffb258 915 break;
wim 15:b70ebfffb258 916
wim 15:b70ebfffb258 917 }
wim 15:b70ebfffb258 918
wim 15:b70ebfffb258 919 }
wim 15:b70ebfffb258 920
wim 15:b70ebfffb258 921 #endif
wim 15:b70ebfffb258 922
wim 15:b70ebfffb258 923
wim 15:b70ebfffb258 924
wim 15:b70ebfffb258 925
wim 15:b70ebfffb258 926 #if(LCD40x4Test)
wim 11:9ec02df863a1 927 void TextLCD::setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 928
wim 15:b70ebfffb258 929 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 930 if(_type==LCD40x4) {
wim 15:b70ebfffb258 931 _LCDCtrl current_ctrl = _ctrl; // Temp save current controller
wim 15:b70ebfffb258 932
wim 15:b70ebfffb258 933 // Select primary controller
wim 15:b70ebfffb258 934 _ctrl=TextLCD::_LCDCtrl_0;
wim 15:b70ebfffb258 935
wim 15:b70ebfffb258 936 // Configure primary LCD controller
wim 15:b70ebfffb258 937 _setUDC(c, udc_data);
wim 15:b70ebfffb258 938
wim 15:b70ebfffb258 939 // Select 2nd controller
wim 15:b70ebfffb258 940 _ctrl=TextLCD::_LCDCtrl_1;
wim 15:b70ebfffb258 941
wim 15:b70ebfffb258 942 // Configure secondary LCD controller
wim 15:b70ebfffb258 943 _setUDC(c, udc_data);
wim 11:9ec02df863a1 944
wim 15:b70ebfffb258 945 // Restore current controller
wim 15:b70ebfffb258 946 _ctrl=current_ctrl;
wim 15:b70ebfffb258 947 }
wim 15:b70ebfffb258 948 else {
wim 15:b70ebfffb258 949 // Configure primary LCD controller
wim 15:b70ebfffb258 950 _setUDC(c, udc_data);
wim 15:b70ebfffb258 951 }
wim 15:b70ebfffb258 952
wim 15:b70ebfffb258 953 }
wim 15:b70ebfffb258 954
wim 15:b70ebfffb258 955 void TextLCD::_setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 956
wim 15:b70ebfffb258 957 // Select CG RAM for current LCD controller
wim 15:b70ebfffb258 958 _writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address,
wim 15:b70ebfffb258 959 //8 sequential locations needed per UDC
wim 15:b70ebfffb258 960 // Store UDC pattern
wim 11:9ec02df863a1 961 for (int i=0; i<8; i++) {
wim 13:24506ba22480 962 _writeData(*udc_data++);
wim 11:9ec02df863a1 963 }
wim 15:b70ebfffb258 964
wim 15:b70ebfffb258 965 //Select DD RAM again for current LCD controller
wim 15:b70ebfffb258 966 int addr = getAddress(_column, _row);
wim 15:b70ebfffb258 967 _writeCommand(0x80 | addr);
wim 15:b70ebfffb258 968
wim 11:9ec02df863a1 969 }
wim 10:dd9b3a696acd 970
wim 15:b70ebfffb258 971 #else
wim 15:b70ebfffb258 972 //standard
wim 15:b70ebfffb258 973 void TextLCD::setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 974 // Select CG RAM for current LCD controller
wim 15:b70ebfffb258 975 _writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address
wim 15:b70ebfffb258 976 //8 sequential locations needed per UDC
wim 15:b70ebfffb258 977 // Store UDC pattern
wim 15:b70ebfffb258 978 for (int i=0; i<8; i++) {
wim 15:b70ebfffb258 979 _writeData(*udc_data++);
wim 15:b70ebfffb258 980 }
wim 15:b70ebfffb258 981
wim 15:b70ebfffb258 982 //Select DD RAM again for current LCD controller
wim 15:b70ebfffb258 983 addr = getAddress(_column, _row);
wim 15:b70ebfffb258 984 _writeCommand(0x80 | addr);
wim 15:b70ebfffb258 985
wim 15:b70ebfffb258 986 }
wim 10:dd9b3a696acd 987
wim 15:b70ebfffb258 988 #endif