The Electronics Nuke / TextLCD

Dependents:   mbed_lcd_custom MMA8451_ACELEROMETRO_copy

Fork of TextLCD by The Electronics Nuke

Committer:
mbeded
Date:
Thu Jul 03 21:13:50 2014 +0000
Revision:
34:c382632a6e27
Parent:
33:ec30a01baf4a
Arduino Alike Lcd Library

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