for

Dependents:   LV_FGSE_Controller_Interface

Committer:
wim
Date:
Tue Jun 17 17:41:47 2014 +0000
Revision:
29:a3663151aa65
Parent:
28:30fa94f7341c
Child:
30:033048611c01
Tested with PCF2116

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
wim 22:35742ec80c24 10 * 2014, v08: WH, Refactored in Base and Derived Classes to deal with mbed lib change regarding 'NC' defined pins
wim 25:6162b31128c9 11 * 2014, v09: WH/EO, Added Class for Native SPI controllers such as ST7032
wim 26:bd897a001012 12 * 2014, v10: WH, Added Class for Native I2C controllers such as ST7032i, Added support for MCP23008 I2C portexpander, Added support for Adafruit module
wim 29:a3663151aa65 13 * 2014, v11: WH, Added support for native I2C controllers such as PCF21XX, improved the _initCtrl() method to deal with differences between all supported controllers
simon 1:ac48b187213c 14 *
simon 1:ac48b187213c 15 * Permission is hereby granted, free of charge, to any person obtaining a copy
simon 1:ac48b187213c 16 * of this software and associated documentation files (the "Software"), to deal
simon 1:ac48b187213c 17 * in the Software without restriction, including without limitation the rights
simon 1:ac48b187213c 18 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 1:ac48b187213c 19 * copies of the Software, and to permit persons to whom the Software is
simon 1:ac48b187213c 20 * furnished to do so, subject to the following conditions:
simon 1:ac48b187213c 21 *
simon 1:ac48b187213c 22 * The above copyright notice and this permission notice shall be included in
simon 1:ac48b187213c 23 * all copies or substantial portions of the Software.
simon 1:ac48b187213c 24 *
simon 1:ac48b187213c 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 1:ac48b187213c 26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 1:ac48b187213c 27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 1:ac48b187213c 28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 1:ac48b187213c 29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 1:ac48b187213c 30 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 1:ac48b187213c 31 * THE SOFTWARE.
simon 1:ac48b187213c 32 */
simon 1:ac48b187213c 33
simon 1:ac48b187213c 34 #include "TextLCD.h"
simon 1:ac48b187213c 35 #include "mbed.h"
simon 1:ac48b187213c 36
wim 29:a3663151aa65 37
wim 29:a3663151aa65 38 DigitalOut led1(LED1);
wim 29:a3663151aa65 39 DigitalOut led2(LED2);
wim 29:a3663151aa65 40
wim 29:a3663151aa65 41
wim 21:9eb628d9e164 42 /** Create a TextLCD_Base interface
wim 15:b70ebfffb258 43 *
wim 21:9eb628d9e164 44 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 21:9eb628d9e164 45 * @param ctrl LCD controller (default = HD44780)
wim 15:b70ebfffb258 46 */
wim 21:9eb628d9e164 47 TextLCD_Base::TextLCD_Base(LCDType type, LCDCtrl ctrl) : _type(type), _ctrl(ctrl) {
wim 14:0c32b66b14b8 48 }
wim 14:0c32b66b14b8 49
wim 14:0c32b66b14b8 50
wim 21:9eb628d9e164 51 /** Init the LCD Controller(s)
wim 21:9eb628d9e164 52 * Clear display
wim 21:9eb628d9e164 53 */
wim 21:9eb628d9e164 54 void TextLCD_Base::_init() {
wim 15:b70ebfffb258 55
wim 15:b70ebfffb258 56 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 57 if(_type==LCD40x4) {
wim 27:22d5086f6ba6 58 _ctrl_idx=_LCDCtrl_1; // Select 2nd controller
wim 15:b70ebfffb258 59
wim 27:22d5086f6ba6 60 _initCtrl(); // Init 2nd controller
wim 15:b70ebfffb258 61
wim 15:b70ebfffb258 62 }
wim 15:b70ebfffb258 63
wim 15:b70ebfffb258 64 // Select and configure primary LCD controller
wim 27:22d5086f6ba6 65 _ctrl_idx=_LCDCtrl_0; // Select primary controller
wim 13:24506ba22480 66
wim 19:c747b9e2e7b8 67 _initCtrl(); // Init primary controller
wim 28:30fa94f7341c 68
wim 28:30fa94f7341c 69 // Reset Cursor location
wim 28:30fa94f7341c 70 _row=0;
wim 28:30fa94f7341c 71 _column=0;
wim 15:b70ebfffb258 72 }
wim 15:b70ebfffb258 73
wim 21:9eb628d9e164 74 /** Init the LCD controller
wim 21:9eb628d9e164 75 * 4-bit mode, number of lines, fonttype, no cursor etc
wim 21:9eb628d9e164 76 *
wim 21:9eb628d9e164 77 */
wim 21:9eb628d9e164 78 void TextLCD_Base::_initCtrl() {
wim 15:b70ebfffb258 79
wim 26:bd897a001012 80 this->_setRS(false); // command mode
wim 13:24506ba22480 81
wim 26:bd897a001012 82 wait_ms(20); // Wait 20ms to ensure powered up
simon 1:ac48b187213c 83
wim 17:652ab113bc2e 84 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
wim 17:652ab113bc2e 85 for (int i=0; i<3; i++) {
wim 17:652ab113bc2e 86 _writeNibble(0x3);
wim 20:e0da005a777f 87 wait_ms(15); // This command takes 1.64ms, so wait for it
wim 17:652ab113bc2e 88 }
wim 17:652ab113bc2e 89 _writeNibble(0x2); // 4-bit mode
wim 17:652ab113bc2e 90 wait_us(40); // most instructions take 40us
wim 18:bd65dc10f27f 91
wim 18:bd65dc10f27f 92 // Display is now in 4-bit mode
wim 27:22d5086f6ba6 93 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 25:6162b31128c9 94
wim 29:a3663151aa65 95 // Device specific initialisations: DC/DC converter to generate VLCD or VLED, number of lines etc
wim 19:c747b9e2e7b8 96 switch (_ctrl) {
wim 29:a3663151aa65 97 case KS0078:
wim 29:a3663151aa65 98
wim 29:a3663151aa65 99 // Initialise Display configuration
wim 29:a3663151aa65 100 switch (_type) {
wim 29:a3663151aa65 101 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 102 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 103 // case LCD12x1:
wim 29:a3663151aa65 104 case LCD16x1:
wim 29:a3663151aa65 105 case LCD24x1:
wim 29:a3663151aa65 106 //@TODO check config
wim 29:a3663151aa65 107 _writeCommand(0x20); // Function set 001 DL N F - -
wim 29:a3663151aa65 108 // DL=0 (4 bits bus)
wim 29:a3663151aa65 109 // N=0 (1 line)
wim 29:a3663151aa65 110 // F=0 (5x7 dots font)
wim 29:a3663151aa65 111 break;
wim 29:a3663151aa65 112
wim 29:a3663151aa65 113 case LCD24x4B:
wim 29:a3663151aa65 114 // Special mode for KS0078
wim 29:a3663151aa65 115 _writeCommand(0x2A); // Function set 001 DL N RE DH REV
wim 29:a3663151aa65 116 // DL=0 (4 bits bus)
wim 29:a3663151aa65 117 // N=1 (Dont care for KS0078)
wim 29:a3663151aa65 118 // RE=0 (Dis. Extended Regs, special mode for KS0078)
wim 29:a3663151aa65 119 // DH=1 (Disp shift, special mode for KS0078)
wim 29:a3663151aa65 120 // REV=0 (Reverse, special mode for KS0078)
wim 29:a3663151aa65 121
wim 29:a3663151aa65 122 _writeCommand(0x2E); // Function set 001 DL N RE DH REV
wim 29:a3663151aa65 123 // DL=0 (4 bits bus)
wim 29:a3663151aa65 124 // N=1 (Dont care for KS0078)
wim 29:a3663151aa65 125 // RE=1 (Ena Extended Regs, special mode for KS0078)
wim 29:a3663151aa65 126 // DH=1 (Disp shift, special mode for KS0078)
wim 29:a3663151aa65 127 // REV=0 (Reverse, special mode for KS0078)
wim 29:a3663151aa65 128
wim 29:a3663151aa65 129 _writeCommand(0x09); // Ext Function set 0000 1 FW BW NW
wim 29:a3663151aa65 130 // FW=0 (5-dot font, special mode for KS0078)
wim 29:a3663151aa65 131 // BW=0 (Cur BW invert disable, special mode for KS0078)
wim 29:a3663151aa65 132 // NW=1 (4 Line, special mode for KS0078)
wim 29:a3663151aa65 133
wim 29:a3663151aa65 134 _writeCommand(0x2A); // Function set 001 DL N RE DH REV
wim 29:a3663151aa65 135 // DL=0 (4 bits bus)
wim 29:a3663151aa65 136 // N=1 (Dont care for KS0078)
wim 29:a3663151aa65 137 // RE=0 (Dis. Extended Regs, special mode for KS0078)
wim 29:a3663151aa65 138 // DH=1 (Disp shift, special mode for KS0078)
wim 29:a3663151aa65 139 // REV=0 (Reverse, special mode for KS0078)
wim 29:a3663151aa65 140
wim 29:a3663151aa65 141 // All other LCD types are initialised as 2 Line displays (including LCD40x4)
wim 29:a3663151aa65 142 default:
wim 29:a3663151aa65 143 //@TODO check config
wim 29:a3663151aa65 144 _writeCommand(0x28); // Function set 001 DL N F - -
wim 29:a3663151aa65 145 // DL=0 (4 bits bus)
wim 29:a3663151aa65 146 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 147 // N=1 (2 lines)
wim 29:a3663151aa65 148 // F=0 (5x7 dots font, only option for 2 line display)
wim 29:a3663151aa65 149 // - (Don't care)
wim 29:a3663151aa65 150
wim 29:a3663151aa65 151 break;
wim 29:a3663151aa65 152 } // switch type
wim 29:a3663151aa65 153
wim 29:a3663151aa65 154 break; // case KS0078 Controller
wim 29:a3663151aa65 155
wim 26:bd897a001012 156 case ST7032_3V3:
wim 26:bd897a001012 157 // ST7032 controller: Initialise Voltage booster for VLCD. VDD=3V3
wim 27:22d5086f6ba6 158
wim 29:a3663151aa65 159 // Initialise Display configuration
wim 29:a3663151aa65 160 switch (_type) {
wim 29:a3663151aa65 161 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 162 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 163 // case LCD12x1:
wim 29:a3663151aa65 164 case LCD16x1:
wim 29:a3663151aa65 165 case LCD24x1:
wim 28:30fa94f7341c 166
wim 29:a3663151aa65 167 // _writeCommand(0x31); //FUNCTION SET 8 bit,N=0 1-line display mode,5*7dot, Select Instruction Set = 1
wim 29:a3663151aa65 168 _writeCommand(0x21); //FUNCTION SET 4 bit, N=0 1-line display mode, 5*7dot, Select Instruction Set = 1
wim 29:a3663151aa65 169 //Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 170
wim 29:a3663151aa65 171 _writeCommand(0x1C); //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4
wim 28:30fa94f7341c 172
wim 29:a3663151aa65 173 _writeCommand(0x73); //Contrast control low byte
wim 28:30fa94f7341c 174
wim 29:a3663151aa65 175 _writeCommand(0x57); //booster circuit is turned on. /ICON display off. /Contrast control high byte
wim 29:a3663151aa65 176 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 177
wim 29:a3663151aa65 178 _writeCommand(0x6C); //Follower control
wim 29:a3663151aa65 179 wait_ms(10); // Wait 10ms to ensure powered up
wim 28:30fa94f7341c 180
wim 29:a3663151aa65 181 // _writeCommand(0x30); //FUNCTION SET 8 bit,N=0 1-line display mode,5*7dot, Return to Instruction Set = 0
wim 29:a3663151aa65 182 _writeCommand(0x20); //FUNCTION SET 4 bit, N=0 1-line display mode, 5*7dot, Return to Instruction Set = 0
wim 29:a3663151aa65 183 //Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 184
wim 29:a3663151aa65 185 break;
wim 29:a3663151aa65 186
wim 29:a3663151aa65 187 default:
wim 29:a3663151aa65 188 // All other LCD types are initialised as 2 Line displays
wim 29:a3663151aa65 189
wim 29:a3663151aa65 190 // _writeCommand(0x39); //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Select Instruction Set = 1
wim 29:a3663151aa65 191 _writeCommand(0x29); //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Select Instruction Set = 1
wim 29:a3663151aa65 192 //Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 193
wim 29:a3663151aa65 194 _writeCommand(0x1C); //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4
wim 29:a3663151aa65 195
wim 29:a3663151aa65 196 _writeCommand(0x73); //Contrast control low byte
wim 29:a3663151aa65 197
wim 29:a3663151aa65 198 _writeCommand(0x57); //booster circuit is turned on. /ICON display off. /Contrast control high byte
wim 29:a3663151aa65 199 wait_ms(10); // Wait 10ms to ensure powered up
wim 28:30fa94f7341c 200
wim 29:a3663151aa65 201 _writeCommand(0x6C); //Follower control
wim 29:a3663151aa65 202 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 203
wim 29:a3663151aa65 204 // _writeCommand(0x38); //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Return to Instruction Set = 0
wim 29:a3663151aa65 205 _writeCommand(0x28); //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Return to Instruction Set = 0
wim 29:a3663151aa65 206 //Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 207 } // switch type
wim 29:a3663151aa65 208
wim 29:a3663151aa65 209 break; // case ST7032_3V3 Controller
wim 26:bd897a001012 210
wim 28:30fa94f7341c 211
wim 26:bd897a001012 212 case ST7032_5V:
wim 26:bd897a001012 213 // ST7032 controller: Disable Voltage booster for VLCD. VDD=5V
wim 29:a3663151aa65 214
wim 29:a3663151aa65 215 // Initialise Display configuration
wim 29:a3663151aa65 216 switch (_type) {
wim 29:a3663151aa65 217 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 218 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 219 // case LCD12x1:
wim 29:a3663151aa65 220 case LCD16x1:
wim 29:a3663151aa65 221 case LCD24x1:
wim 29:a3663151aa65 222
wim 29:a3663151aa65 223 // _writeCommand(0x31); //FUNCTION SET 8 bit,N=0 1-line display mode,5*7dot, Select Instruction Set = 1
wim 29:a3663151aa65 224 _writeCommand(0x21); //FUNCTION SET 4 bit, N=0 1-line display mode, 5*7dot, Select Instruction Set = 1
wim 29:a3663151aa65 225 //Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 226
wim 29:a3663151aa65 227 _writeCommand(0x1C); //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4
wim 29:a3663151aa65 228
wim 29:a3663151aa65 229 _writeCommand(0x73); //Contrast control low byte
wim 28:30fa94f7341c 230
wim 29:a3663151aa65 231 _writeCommand(0x53); //booster circuit is turned off. /ICON display off. /Contrast control high byte
wim 29:a3663151aa65 232 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 233
wim 29:a3663151aa65 234 _writeCommand(0x6C); //Follower control
wim 29:a3663151aa65 235 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 236
wim 29:a3663151aa65 237 // _writeCommand(0x30); //FUNCTION SET 8 bit,N=0 1-line display mode,5*7dot, Return to Instruction Set = 0
wim 29:a3663151aa65 238 _writeCommand(0x20); //FUNCTION SET 4 bit, N=0 1-line display mode, 5*7dot, Return to Instruction Set = 0
wim 29:a3663151aa65 239 //Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 240
wim 29:a3663151aa65 241 break;
wim 28:30fa94f7341c 242
wim 29:a3663151aa65 243 default:
wim 29:a3663151aa65 244 // All other LCD types are initialised as 2 Line displays
wim 29:a3663151aa65 245
wim 29:a3663151aa65 246 // _writeCommand(0x39); //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Select Instruction Set = 1
wim 29:a3663151aa65 247 _writeCommand(0x29); //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Select Instruction Set = 1
wim 29:a3663151aa65 248 //Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 249
wim 29:a3663151aa65 250 _writeCommand(0x1C); //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4
wim 29:a3663151aa65 251
wim 29:a3663151aa65 252 _writeCommand(0x73); //Contrast control low byte
wim 29:a3663151aa65 253
wim 29:a3663151aa65 254 _writeCommand(0x53); //booster circuit is turned off. /ICON display off. /Contrast control high byte
wim 29:a3663151aa65 255 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 256
wim 29:a3663151aa65 257 _writeCommand(0x6C); //Follower control
wim 29:a3663151aa65 258 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 259
wim 29:a3663151aa65 260 // _writeCommand(0x38); //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Return to Instruction Set = 0
wim 29:a3663151aa65 261 _writeCommand(0x28); //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Return to Instruction Set = 0
wim 29:a3663151aa65 262 //Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 263 } // switch type
wim 29:a3663151aa65 264
wim 29:a3663151aa65 265 break; // case ST7032_5V Controller
wim 28:30fa94f7341c 266
wim 29:a3663151aa65 267 case ST7036:
wim 29:a3663151aa65 268 // ST7036 controller: Initialise Voltage booster for VLCD. VDD=5V
wim 29:a3663151aa65 269 // Note: supports 1,2 or 3 lines
wim 28:30fa94f7341c 270
wim 29:a3663151aa65 271 // Initialise Display configuration
wim 29:a3663151aa65 272 switch (_type) {
wim 29:a3663151aa65 273 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 274 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 275 // case LCD12x1:
wim 29:a3663151aa65 276 case LCD16x1:
wim 29:a3663151aa65 277 case LCD24x1:
wim 29:a3663151aa65 278 _writeCommand(0x21); // 4-bit Databus, N=0 1 Line, DH=0 5x7font, IS2,IS1 = 01 Select Instruction Set = 1
wim 29:a3663151aa65 279 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 280 _writeCommand(0x14); // Bias: 1/5, 1 or 2-Lines LCD
wim 29:a3663151aa65 281 // _writeCommand(0x15); // Bias: 1/5, 3-Lines LCD
wim 29:a3663151aa65 282 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 283 _writeCommand(0x55); // Icon off, Booster on, Set Contrast C5, C4
wim 29:a3663151aa65 284 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 285 _writeCommand(0x6D); // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
wim 29:a3663151aa65 286 wait_ms(200); // > 200ms!
wim 29:a3663151aa65 287 _writeCommand(0x78); // Set Contrast C3, C2, C1, C0
wim 29:a3663151aa65 288 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 289 _writeCommand(0x20); // Return to Instruction Set = 0
wim 29:a3663151aa65 290 wait_ms(50);
wim 29:a3663151aa65 291 break;
wim 29:a3663151aa65 292 #if(0)
wim 29:a3663151aa65 293 // case LCD12x3:
wim 29:a3663151aa65 294 case LCD16x3:
wim 29:a3663151aa65 295 _writeCommand(0x29); // 4-bit Databus, N=1 2 Line, DH=0 5x7font, IS2,IS1 = 01 Select Instruction Set = 1
wim 29:a3663151aa65 296 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 297 // _writeCommand(0x14); // Bias: 1/5, 1 or 2-Lines LCD
wim 29:a3663151aa65 298 _writeCommand(0x15); // Bias: 1/5, 3-Lines LCD
wim 29:a3663151aa65 299 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 300 _writeCommand(0x55); // Icon off, Booster on, Set Contrast C5, C4
wim 29:a3663151aa65 301 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 302 _writeCommand(0x6D); // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
wim 29:a3663151aa65 303 wait_ms(200); // > 200ms!
wim 29:a3663151aa65 304 _writeCommand(0x78); // Set Contrast C3, C2, C1, C0
wim 29:a3663151aa65 305 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 306 _writeCommand(0x28); // Return to Instruction Set = 0
wim 29:a3663151aa65 307 wait_ms(50);
wim 29:a3663151aa65 308 break;
wim 29:a3663151aa65 309 #endif
wim 29:a3663151aa65 310 default:
wim 29:a3663151aa65 311 // All other LCD types are initialised as 2 Line displays
wim 29:a3663151aa65 312 _writeCommand(0x29); // 4-bit Databus, N=1 2 Line, DH=0 5x7font, IS2,IS1 = 01 Select Instruction Set = 1
wim 29:a3663151aa65 313 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 314 _writeCommand(0x14); // Bias: 1/5, 2-Lines LCD
wim 29:a3663151aa65 315 // _writeCommand(0x15); // Bias: 1/5, 3-Lines LCD
wim 29:a3663151aa65 316 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 317 _writeCommand(0x55); // Icon off, Booster on, Set Contrast C5, C4
wim 29:a3663151aa65 318 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 319 _writeCommand(0x6D); // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
wim 29:a3663151aa65 320 wait_ms(200); // > 200ms!
wim 29:a3663151aa65 321 _writeCommand(0x78); // Set Contrast C3, C2, C1, C0
wim 29:a3663151aa65 322 wait_ms(30); // > 26,3ms
wim 29:a3663151aa65 323 _writeCommand(0x28); // Return to Instruction Set = 0
wim 29:a3663151aa65 324 wait_ms(50);
wim 29:a3663151aa65 325 } // switch type
wim 29:a3663151aa65 326
wim 29:a3663151aa65 327 break; // case ST7036 Controller
wim 29:a3663151aa65 328
wim 29:a3663151aa65 329 case PCF21XX_3V3:
wim 29:a3663151aa65 330 // PCF21XX controller: Initialise Voltage booster for VLCD. VDD=3V3
wim 28:30fa94f7341c 331
wim 29:a3663151aa65 332 // Initialise Display configuration
wim 29:a3663151aa65 333 switch (_type) {
wim 29:a3663151aa65 334 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 335 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 336 // case LCD12x1:
wim 29:a3663151aa65 337 case LCD16x1:
wim 29:a3663151aa65 338 case LCD24x1:
wim 29:a3663151aa65 339 _writeCommand(0x22); //FUNCTION SET 4 bit, N=0/M=0 1-line/24 chars display mode, G=1 Booster on
wim 29:a3663151aa65 340 //Note: 4 bit mode is ignored for I2C mode
wim 29:a3663151aa65 341 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 342 break;
wim 29:a3663151aa65 343
wim 29:a3663151aa65 344 case LCD12x3B:
wim 29:a3663151aa65 345 case LCD12x4B:
wim 29:a3663151aa65 346 _writeCommand(0x2E); //FUNCTION SET 4 bit, N=1/M=1 4-line/12 chars display mode, G=1 Booster on
wim 29:a3663151aa65 347 //Note: 4 bit mode is ignored for I2C mode
wim 29:a3663151aa65 348 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 349 break;
wim 29:a3663151aa65 350
wim 29:a3663151aa65 351 default:
wim 29:a3663151aa65 352 // All other LCD types are initialised as 2 Line displays
wim 29:a3663151aa65 353 _writeCommand(0x2A); //FUNCTION SET 4 bit, N=1/M=0 2-line/24 chars display mode, G=1 Booster on
wim 29:a3663151aa65 354 //Note: 4 bit mode is ignored for I2C mode
wim 29:a3663151aa65 355
wim 29:a3663151aa65 356 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 357
wim 29:a3663151aa65 358
wim 29:a3663151aa65 359 led1=!led1;
wim 29:a3663151aa65 360 } // switch type
wim 29:a3663151aa65 361
wim 29:a3663151aa65 362
wim 29:a3663151aa65 363 break; // case PCF21XX_3V3 Controller
wim 29:a3663151aa65 364
wim 29:a3663151aa65 365
wim 29:a3663151aa65 366 // case PCF21XX_5V:
wim 29:a3663151aa65 367 // PCF21XX controller: No Voltage booster for VLCD. VDD=5V
wim 29:a3663151aa65 368
wim 29:a3663151aa65 369
wim 19:c747b9e2e7b8 370 case WS0010:
wim 19:c747b9e2e7b8 371 // WS0010 OLED controller: Initialise DC/DC Voltage converter for LEDs
wim 19:c747b9e2e7b8 372 // Note: supports 1 or 2 lines (and 16x100 graphics)
wim 19:c747b9e2e7b8 373 // supports 4 fonts (English/Japanese (default), Western European-I, English/Russian, Western European-II)
wim 19:c747b9e2e7b8 374 // Cursor/Disp shift set 0001 SC RL 0 0
wim 19:c747b9e2e7b8 375 //
wim 19:c747b9e2e7b8 376 // Mode en Power set 0001 GC PWR 1 1
wim 19:c747b9e2e7b8 377 // GC = 0 (Graph Mode=1, Char Mode=0)
wim 19:c747b9e2e7b8 378 // PWR = (DC/DC On/Off)
wim 19:c747b9e2e7b8 379
wim 25:6162b31128c9 380 //_writeCommand(0x13); // DC/DC off
wim 28:30fa94f7341c 381 _writeCommand(0x17); // DC/DC on
wim 28:30fa94f7341c 382 wait_ms(10); // Wait 10ms to ensure powered up
wim 25:6162b31128c9 383
wim 29:a3663151aa65 384
wim 29:a3663151aa65 385 // Initialise Display configuration
wim 29:a3663151aa65 386 switch (_type) {
wim 29:a3663151aa65 387 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 388 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 389 // case LCD12x1:
wim 29:a3663151aa65 390 case LCD16x1:
wim 29:a3663151aa65 391 // case LCD24x1:
wim 29:a3663151aa65 392 _writeCommand(0x20); // Function set 001 DL N F - -
wim 29:a3663151aa65 393 // DL=0 (4 bits bus)
wim 29:a3663151aa65 394 // N=0 (1 line)
wim 29:a3663151aa65 395 // F=0 (5x7 dots font)
wim 29:a3663151aa65 396 break;
wim 29:a3663151aa65 397
wim 29:a3663151aa65 398 default:
wim 29:a3663151aa65 399 // All other LCD types are initialised as 2 Line displays (including LCD40x4)
wim 29:a3663151aa65 400 _writeCommand(0x28); // Function set 001 DL N F - -
wim 29:a3663151aa65 401 // DL=0 (4 bits bus)
wim 29:a3663151aa65 402 // N=1 (2 lines)
wim 29:a3663151aa65 403 // F=0 (5x7 dots font, only option for 2 line display)
wim 29:a3663151aa65 404 // - (Don't care)
wim 29:a3663151aa65 405
wim 29:a3663151aa65 406 break;
wim 29:a3663151aa65 407 } // switch type
wim 29:a3663151aa65 408
wim 29:a3663151aa65 409 break; // case WS0100 Controller
wim 29:a3663151aa65 410
wim 19:c747b9e2e7b8 411 default:
wim 29:a3663151aa65 412 // Devices fully compatible to HD44780 that do not use any DC/DC Voltage converters but external VLCD
wim 10:dd9b3a696acd 413
wim 29:a3663151aa65 414 // Initialise Display configuration
wim 29:a3663151aa65 415 switch (_type) {
wim 29:a3663151aa65 416 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 417 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 418 // case LCD12x1:
wim 29:a3663151aa65 419 case LCD16x1:
wim 29:a3663151aa65 420 case LCD24x1:
wim 29:a3663151aa65 421 _writeCommand(0x20); // Function set 001 DL N F - -
wim 29:a3663151aa65 422 // DL=0 (4 bits bus)
wim 29:a3663151aa65 423 // N=0 (1 line)
wim 29:a3663151aa65 424 // F=0 (5x7 dots font)
wim 29:a3663151aa65 425 break;
wim 29:a3663151aa65 426
wim 29:a3663151aa65 427 // All other LCD types are initialised as 2 Line displays (including LCD40x4)
wim 29:a3663151aa65 428 default:
wim 29:a3663151aa65 429 _writeCommand(0x28); // Function set 001 DL N F - -
wim 29:a3663151aa65 430 // DL=0 (4 bits bus)
wim 29:a3663151aa65 431 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 432 // N=1 (2 lines)
wim 29:a3663151aa65 433 // F=0 (5x7 dots font, only option for 2 line display)
wim 29:a3663151aa65 434 // - (Don't care)
wim 29:a3663151aa65 435
wim 29:a3663151aa65 436 break;
wim 29:a3663151aa65 437 } // switch type
wim 10:dd9b3a696acd 438
wim 29:a3663151aa65 439 break; // case default Controller
wim 29:a3663151aa65 440
wim 29:a3663151aa65 441 } // switch Controller specific initialisations
wim 29:a3663151aa65 442
wim 10:dd9b3a696acd 443
wim 29:a3663151aa65 444 // Controller general initialisations
wim 29:a3663151aa65 445
wim 28:30fa94f7341c 446 _writeCommand(0x01); // cls, and set cursor to 0
wim 28:30fa94f7341c 447 wait_ms(10); // The CLS command takes 1.64 ms.
wim 28:30fa94f7341c 448 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 28:30fa94f7341c 449
wim 28:30fa94f7341c 450 _writeCommand(0x02); // Return Home
wim 28:30fa94f7341c 451 // Cursor Home, DDRAM Address to Origin
wim 28:30fa94f7341c 452
wim 28:30fa94f7341c 453 _writeCommand(0x06); // Entry Mode 0000 0 1 I/D S
wim 13:24506ba22480 454 // Cursor Direction and Display Shift
wim 28:30fa94f7341c 455 // I/D=1 (Cur incr)
wim 28:30fa94f7341c 456 // S=0 (No display shift)
wim 10:dd9b3a696acd 457
wim 29:a3663151aa65 458 _writeCommand(0x14); // Cursor or Display shift 0001 S/C R/L x x
wim 29:a3663151aa65 459 // S/C=0 Cursor moves
wim 29:a3663151aa65 460 // R/L=1 Right
wim 29:a3663151aa65 461 //
wim 29:a3663151aa65 462
wim 29:a3663151aa65 463
wim 13:24506ba22480 464 // _writeCommand(0x0C); // Display Ctrl 0000 1 D C B
wim 17:652ab113bc2e 465 // // Display On, Cursor Off, Blink Off
wim 21:9eb628d9e164 466 setCursor(CurOff_BlkOff);
wim 21:9eb628d9e164 467 setMode(DispOn);
wim 29:a3663151aa65 468 led2=!led2;
simon 1:ac48b187213c 469 }
simon 1:ac48b187213c 470
wim 8:03116f75b66e 471
wim 21:9eb628d9e164 472 /** Clear the screen, Cursor home.
wim 21:9eb628d9e164 473 */
wim 21:9eb628d9e164 474 void TextLCD_Base::cls() {
wim 15:b70ebfffb258 475
wim 15:b70ebfffb258 476 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 477 if(_type==LCD40x4) {
wim 21:9eb628d9e164 478 _ctrl_idx=_LCDCtrl_1; // Select 2nd controller
wim 15:b70ebfffb258 479
wim 15:b70ebfffb258 480 // Second LCD controller Cursor always Off
wim 21:9eb628d9e164 481 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 15:b70ebfffb258 482
wim 15:b70ebfffb258 483 // Second LCD controller Clearscreen
wim 27:22d5086f6ba6 484 _writeCommand(0x01); // cls, and set cursor to 0
wim 29:a3663151aa65 485 wait_ms(10); // The CLS command takes 1.64 ms.
wim 29:a3663151aa65 486 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 15:b70ebfffb258 487
wim 21:9eb628d9e164 488 _ctrl_idx=_LCDCtrl_0; // Select primary controller
wim 15:b70ebfffb258 489 }
wim 15:b70ebfffb258 490
wim 15:b70ebfffb258 491 // Primary LCD controller Clearscreen
wim 27:22d5086f6ba6 492 _writeCommand(0x01); // cls, and set cursor to 0
wim 29:a3663151aa65 493 wait_ms(10); // The CLS command takes 1.64 ms.
wim 29:a3663151aa65 494 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 15:b70ebfffb258 495
wim 15:b70ebfffb258 496 // Restore cursormode on primary LCD controller when needed
wim 15:b70ebfffb258 497 if(_type==LCD40x4) {
wim 17:652ab113bc2e 498 _setCursorAndDisplayMode(_currentMode,_currentCursor);
wim 15:b70ebfffb258 499 }
wim 15:b70ebfffb258 500
wim 29:a3663151aa65 501 setAddress(0, 0); // Reset Cursor location
wim 29:a3663151aa65 502 // Note: this is needed because some rare displays (eg PCF21XX) don't use line 0 in the '3 Line' mode.
simon 1:ac48b187213c 503 }
simon 1:ac48b187213c 504
wim 29:a3663151aa65 505 /** Locate cursor to a screen column and row
wim 29:a3663151aa65 506 *
wim 29:a3663151aa65 507 * @param column The horizontal position from the left, indexed from 0
wim 29:a3663151aa65 508 * @param row The vertical position from the top, indexed from 0
wim 29:a3663151aa65 509 */
wim 21:9eb628d9e164 510 void TextLCD_Base::locate(int column, int row) {
wim 15:b70ebfffb258 511
wim 15:b70ebfffb258 512 // setAddress() does all the heavy lifting:
wim 15:b70ebfffb258 513 // check column and row sanity,
wim 15:b70ebfffb258 514 // switch controllers for LCD40x4 if needed
wim 15:b70ebfffb258 515 // switch cursor for LCD40x4 if needed
wim 15:b70ebfffb258 516 // set the new memory address to show cursor at correct location
wim 15:b70ebfffb258 517 setAddress(column, row);
wim 15:b70ebfffb258 518
wim 15:b70ebfffb258 519 }
wim 15:b70ebfffb258 520
wim 15:b70ebfffb258 521
wim 21:9eb628d9e164 522 /** Write a single character (Stream implementation)
wim 21:9eb628d9e164 523 */
wim 21:9eb628d9e164 524 int TextLCD_Base::_putc(int value) {
wim 15:b70ebfffb258 525 int addr;
wim 15:b70ebfffb258 526
wim 15:b70ebfffb258 527 if (value == '\n') {
wim 15:b70ebfffb258 528 //No character to write
wim 15:b70ebfffb258 529
wim 15:b70ebfffb258 530 //Update Cursor
wim 15:b70ebfffb258 531 _column = 0;
wim 15:b70ebfffb258 532 _row++;
wim 15:b70ebfffb258 533 if (_row >= rows()) {
wim 15:b70ebfffb258 534 _row = 0;
wim 15:b70ebfffb258 535 }
wim 15:b70ebfffb258 536 }
wim 15:b70ebfffb258 537 else {
wim 15:b70ebfffb258 538 //Character to write
wim 15:b70ebfffb258 539 _writeData(value);
wim 15:b70ebfffb258 540
wim 15:b70ebfffb258 541 //Update Cursor
wim 15:b70ebfffb258 542 _column++;
wim 15:b70ebfffb258 543 if (_column >= columns()) {
wim 15:b70ebfffb258 544 _column = 0;
wim 15:b70ebfffb258 545 _row++;
wim 15:b70ebfffb258 546 if (_row >= rows()) {
wim 15:b70ebfffb258 547 _row = 0;
wim 15:b70ebfffb258 548 }
wim 15:b70ebfffb258 549 }
wim 15:b70ebfffb258 550 } //else
wim 15:b70ebfffb258 551
wim 15:b70ebfffb258 552 //Set next memoryaddress, make sure cursor blinks at next location
wim 15:b70ebfffb258 553 addr = getAddress(_column, _row);
wim 15:b70ebfffb258 554 _writeCommand(0x80 | addr);
wim 15:b70ebfffb258 555
wim 15:b70ebfffb258 556 return value;
wim 15:b70ebfffb258 557 }
wim 15:b70ebfffb258 558
wim 15:b70ebfffb258 559
wim 16:c276b75e6585 560 // get a single character (Stream implementation)
wim 21:9eb628d9e164 561 int TextLCD_Base::_getc() {
simon 1:ac48b187213c 562 return -1;
simon 1:ac48b187213c 563 }
simon 1:ac48b187213c 564
wim 14:0c32b66b14b8 565
wim 17:652ab113bc2e 566 // Write a nibble using the 4-bit interface
wim 21:9eb628d9e164 567 void TextLCD_Base::_writeNibble(int value) {
wim 17:652ab113bc2e 568
wim 17:652ab113bc2e 569 // Enable is Low
wim 21:9eb628d9e164 570 this->_setEnable(true);
wim 21:9eb628d9e164 571 this->_setData(value & 0x0F); // Low nibble
wim 17:652ab113bc2e 572 wait_us(1); // Data setup time
wim 21:9eb628d9e164 573 this->_setEnable(false);
wim 17:652ab113bc2e 574 wait_us(1); // Datahold time
wim 17:652ab113bc2e 575
wim 17:652ab113bc2e 576 // Enable is Low
wim 17:652ab113bc2e 577
wim 17:652ab113bc2e 578 }
wim 17:652ab113bc2e 579
wim 17:652ab113bc2e 580
wim 16:c276b75e6585 581 // Write a byte using the 4-bit interface
wim 21:9eb628d9e164 582 void TextLCD_Base::_writeByte(int value) {
wim 15:b70ebfffb258 583
wim 15:b70ebfffb258 584 // Enable is Low
wim 21:9eb628d9e164 585 this->_setEnable(true);
wim 21:9eb628d9e164 586 this->_setData(value >> 4); // High nibble
wim 15:b70ebfffb258 587 wait_us(1); // Data setup time
wim 21:9eb628d9e164 588 this->_setEnable(false);
wim 15:b70ebfffb258 589 wait_us(1); // Data hold time
wim 15:b70ebfffb258 590
wim 21:9eb628d9e164 591 this->_setEnable(true);
wim 21:9eb628d9e164 592 this->_setData(value >> 0); // Low nibble
wim 15:b70ebfffb258 593 wait_us(1); // Data setup time
wim 21:9eb628d9e164 594 this->_setEnable(false);
wim 15:b70ebfffb258 595 wait_us(1); // Datahold time
wim 15:b70ebfffb258 596
wim 15:b70ebfffb258 597 // Enable is Low
wim 15:b70ebfffb258 598
simon 1:ac48b187213c 599 }
simon 1:ac48b187213c 600
wim 21:9eb628d9e164 601 // Write a command byte to the LCD controller
wim 21:9eb628d9e164 602 void TextLCD_Base::_writeCommand(int command) {
wim 15:b70ebfffb258 603
wim 21:9eb628d9e164 604 this->_setRS(false);
wim 16:c276b75e6585 605 wait_us(1); // Data setup time for RS
wim 15:b70ebfffb258 606
wim 21:9eb628d9e164 607 this->_writeByte(command);
wim 15:b70ebfffb258 608 wait_us(40); // most instructions take 40us
simon 1:ac48b187213c 609 }
simon 1:ac48b187213c 610
wim 21:9eb628d9e164 611 // Write a data byte to the LCD controller
wim 21:9eb628d9e164 612 void TextLCD_Base::_writeData(int data) {
wim 15:b70ebfffb258 613
wim 21:9eb628d9e164 614 this->_setRS(true);
wim 16:c276b75e6585 615 wait_us(1); // Data setup time for RS
wim 15:b70ebfffb258 616
wim 21:9eb628d9e164 617 this->_writeByte(data);
wim 15:b70ebfffb258 618 wait_us(40); // data writes take 40us
simon 1:ac48b187213c 619 }
simon 1:ac48b187213c 620
wim 8:03116f75b66e 621
wim 8:03116f75b66e 622 #if (0)
wim 16:c276b75e6585 623 // This is the original _address() method.
wim 8:03116f75b66e 624 // It is confusing since it returns the memoryaddress or-ed with the set memorycommand 0x80.
wim 8:03116f75b66e 625 // Left it in here for compatibility with older code. New applications should use getAddress() instead.
wim 8:03116f75b66e 626 //
wim 21:9eb628d9e164 627 int TextLCD_Base::_address(int column, int row) {
simon 1:ac48b187213c 628 switch (_type) {
simon 1:ac48b187213c 629 case LCD20x4:
simon 1:ac48b187213c 630 switch (row) {
simon 1:ac48b187213c 631 case 0:
simon 1:ac48b187213c 632 return 0x80 + column;
simon 1:ac48b187213c 633 case 1:
simon 1:ac48b187213c 634 return 0xc0 + column;
simon 1:ac48b187213c 635 case 2:
simon 1:ac48b187213c 636 return 0x94 + column;
simon 1:ac48b187213c 637 case 3:
simon 1:ac48b187213c 638 return 0xd4 + column;
simon 1:ac48b187213c 639 }
simon 1:ac48b187213c 640 case LCD16x2B:
simon 4:bf5b706f8d32 641 return 0x80 + (row * 40) + column;
simon 1:ac48b187213c 642 case LCD16x2:
simon 1:ac48b187213c 643 case LCD20x2:
simon 1:ac48b187213c 644 default:
simon 4:bf5b706f8d32 645 return 0x80 + (row * 0x40) + column;
simon 1:ac48b187213c 646 }
simon 1:ac48b187213c 647 }
wim 8:03116f75b66e 648 #endif
wim 8:03116f75b66e 649
wim 8:03116f75b66e 650
wim 16:c276b75e6585 651 // This replaces the original _address() method.
wim 8:03116f75b66e 652 // Left it in here for compatibility with older code. New applications should use getAddress() instead.
wim 21:9eb628d9e164 653 int TextLCD_Base::_address(int column, int row) {
wim 8:03116f75b66e 654 return 0x80 | getAddress(column, row);
wim 8:03116f75b66e 655 }
wim 8:03116f75b66e 656
wim 8:03116f75b66e 657 // This is new method to return the memory address based on row, column and displaytype.
wim 8:03116f75b66e 658 //
wim 29:a3663151aa65 659 /** Return the memoryaddress of screen column and row location
wim 29:a3663151aa65 660 *
wim 29:a3663151aa65 661 * @param column The horizontal position from the left, indexed from 0
wim 29:a3663151aa65 662 * @param row The vertical position from the top, indexed from 0
wim 29:a3663151aa65 663 * @param return The memoryaddress of screen column and row location
wim 29:a3663151aa65 664 */
wim 21:9eb628d9e164 665 int TextLCD_Base::getAddress(int column, int row) {
wim 8:03116f75b66e 666
wim 8:03116f75b66e 667 switch (_type) {
wim 8:03116f75b66e 668 case LCD8x1:
wim 29:a3663151aa65 669 case LCD24x1:
wim 8:03116f75b66e 670 return 0x00 + column;
wim 18:bd65dc10f27f 671
wim 29:a3663151aa65 672 case LCD16x1:
wim 29:a3663151aa65 673 // LCD16x1 is a special layout of LCD8x2
wim 29:a3663151aa65 674 if (column<8)
wim 29:a3663151aa65 675 return 0x00 + column;
wim 29:a3663151aa65 676 else
wim 29:a3663151aa65 677 return 0x40 + (column - 8);
wim 29:a3663151aa65 678
wim 18:bd65dc10f27f 679 case LCD8x2B:
wim 18:bd65dc10f27f 680 // LCD8x2B is a special layout of LCD16x1
wim 18:bd65dc10f27f 681 if (row==0)
wim 18:bd65dc10f27f 682 return 0x00 + column;
wim 18:bd65dc10f27f 683 else
wim 18:bd65dc10f27f 684 return 0x08 + column;
wim 18:bd65dc10f27f 685
wim 29:a3663151aa65 686 case LCD8x2:
wim 29:a3663151aa65 687 case LCD12x2:
wim 29:a3663151aa65 688 case LCD16x2:
wim 29:a3663151aa65 689 case LCD20x2:
wim 29:a3663151aa65 690 case LCD24x2:
wim 29:a3663151aa65 691 case LCD40x2:
wim 29:a3663151aa65 692 return 0x00 + (row * 0x40) + column;
wim 13:24506ba22480 693
wim 29:a3663151aa65 694 // Not sure about this one, seems wrong.
wim 29:a3663151aa65 695 // Left in for compatibility with original library
wim 29:a3663151aa65 696 case LCD16x2B:
wim 29:a3663151aa65 697 return 0x00 + (row * 40) + column;
wim 29:a3663151aa65 698
wim 29:a3663151aa65 699
wim 28:30fa94f7341c 700 // Special mode for ST7036
wim 28:30fa94f7341c 701 // case LCD16x3:
wim 28:30fa94f7341c 702
wim 29:a3663151aa65 703 // Special mode for PCF2116
wim 29:a3663151aa65 704 case LCD12x3B:
wim 29:a3663151aa65 705 switch (row) {
wim 29:a3663151aa65 706 case 0:
wim 29:a3663151aa65 707 return 0x20 + column;
wim 29:a3663151aa65 708 case 1:
wim 29:a3663151aa65 709 return 0x40 + column;
wim 29:a3663151aa65 710 case 2:
wim 29:a3663151aa65 711 return 0x60 + column;
wim 29:a3663151aa65 712 }
wim 29:a3663151aa65 713
wim 29:a3663151aa65 714 case LCD12x4:
wim 28:30fa94f7341c 715 switch (row) {
wim 28:30fa94f7341c 716 case 0:
wim 28:30fa94f7341c 717 return 0x00 + column;
wim 28:30fa94f7341c 718 case 1:
wim 29:a3663151aa65 719 return 0x40 + column;
wim 28:30fa94f7341c 720 case 2:
wim 29:a3663151aa65 721 return 0x0C + column;
wim 29:a3663151aa65 722 case 3:
wim 29:a3663151aa65 723 return 0x4C + column;
wim 28:30fa94f7341c 724 }
wim 28:30fa94f7341c 725
wim 28:30fa94f7341c 726 // Special mode for PCF2116 (and KS0078)
wim 28:30fa94f7341c 727 case LCD12x4B:
wim 28:30fa94f7341c 728 switch (row) {
wim 28:30fa94f7341c 729 case 0:
wim 28:30fa94f7341c 730 return 0x00 + column;
wim 28:30fa94f7341c 731 case 1:
wim 28:30fa94f7341c 732 return 0x20 + column;
wim 28:30fa94f7341c 733 case 2:
wim 28:30fa94f7341c 734 return 0x40 + column;
wim 28:30fa94f7341c 735 case 3:
wim 28:30fa94f7341c 736 return 0x60 + column;
wim 28:30fa94f7341c 737 }
wim 28:30fa94f7341c 738
wim 8:03116f75b66e 739 case LCD16x4:
wim 8:03116f75b66e 740 switch (row) {
wim 8:03116f75b66e 741 case 0:
wim 8:03116f75b66e 742 return 0x00 + column;
wim 8:03116f75b66e 743 case 1:
wim 8:03116f75b66e 744 return 0x40 + column;
wim 8:03116f75b66e 745 case 2:
wim 8:03116f75b66e 746 return 0x10 + column;
wim 8:03116f75b66e 747 case 3:
wim 8:03116f75b66e 748 return 0x50 + column;
wim 8:03116f75b66e 749 }
wim 8:03116f75b66e 750
wim 8:03116f75b66e 751 case LCD20x4:
wim 8:03116f75b66e 752 switch (row) {
wim 8:03116f75b66e 753 case 0:
wim 8:03116f75b66e 754 return 0x00 + column;
wim 8:03116f75b66e 755 case 1:
wim 8:03116f75b66e 756 return 0x40 + column;
wim 8:03116f75b66e 757 case 2:
wim 8:03116f75b66e 758 return 0x14 + column;
wim 8:03116f75b66e 759 case 3:
wim 8:03116f75b66e 760 return 0x54 + column;
wim 8:03116f75b66e 761 }
wim 8:03116f75b66e 762
wim 10:dd9b3a696acd 763 // Special mode for KS0078
wim 29:a3663151aa65 764 case LCD24x4B:
wim 10:dd9b3a696acd 765 switch (row) {
wim 10:dd9b3a696acd 766 case 0:
wim 10:dd9b3a696acd 767 return 0x00 + column;
wim 10:dd9b3a696acd 768 case 1:
wim 10:dd9b3a696acd 769 return 0x20 + column;
wim 10:dd9b3a696acd 770 case 2:
wim 10:dd9b3a696acd 771 return 0x40 + column;
wim 10:dd9b3a696acd 772 case 3:
wim 10:dd9b3a696acd 773 return 0x60 + column;
wim 10:dd9b3a696acd 774 }
wim 10:dd9b3a696acd 775
wim 15:b70ebfffb258 776 case LCD40x4:
wim 15:b70ebfffb258 777 // LCD40x4 is a special case since it has 2 controllers
wim 15:b70ebfffb258 778 // Each controller is configured as 40x2
wim 15:b70ebfffb258 779 if (row<2) {
wim 15:b70ebfffb258 780 // Test to see if we need to switch between controllers
wim 19:c747b9e2e7b8 781 if (_ctrl_idx != _LCDCtrl_0) {
wim 17:652ab113bc2e 782
wim 15:b70ebfffb258 783 // Second LCD controller Cursor Off
wim 21:9eb628d9e164 784 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 15:b70ebfffb258 785
wim 15:b70ebfffb258 786 // Select primary controller
wim 19:c747b9e2e7b8 787 _ctrl_idx = _LCDCtrl_0;
wim 15:b70ebfffb258 788
wim 15:b70ebfffb258 789 // Restore cursormode on primary LCD controller
wim 17:652ab113bc2e 790 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 15:b70ebfffb258 791 }
wim 15:b70ebfffb258 792
wim 15:b70ebfffb258 793 return 0x00 + (row * 0x40) + column;
wim 15:b70ebfffb258 794 }
wim 15:b70ebfffb258 795 else {
wim 15:b70ebfffb258 796
wim 15:b70ebfffb258 797 // Test to see if we need to switch between controllers
wim 19:c747b9e2e7b8 798 if (_ctrl_idx != _LCDCtrl_1) {
wim 15:b70ebfffb258 799 // Primary LCD controller Cursor Off
wim 21:9eb628d9e164 800 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 15:b70ebfffb258 801
wim 15:b70ebfffb258 802 // Select secondary controller
wim 19:c747b9e2e7b8 803 _ctrl_idx = _LCDCtrl_1;
wim 15:b70ebfffb258 804
wim 15:b70ebfffb258 805 // Restore cursormode on secondary LCD controller
wim 17:652ab113bc2e 806 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 15:b70ebfffb258 807 }
wim 15:b70ebfffb258 808
wim 15:b70ebfffb258 809 return 0x00 + ((row-2) * 0x40) + column;
wim 15:b70ebfffb258 810 }
wim 8:03116f75b66e 811
wim 8:03116f75b66e 812 // Should never get here.
wim 8:03116f75b66e 813 default:
wim 8:03116f75b66e 814 return 0x00;
wim 8:03116f75b66e 815 }
wim 8:03116f75b66e 816 }
wim 8:03116f75b66e 817
wim 8:03116f75b66e 818
wim 29:a3663151aa65 819 /** Set the memoryaddress of screen column and row location
wim 29:a3663151aa65 820 *
wim 29:a3663151aa65 821 * @param column The horizontal position from the left, indexed from 0
wim 29:a3663151aa65 822 * @param row The vertical position from the top, indexed from 0
wim 29:a3663151aa65 823 */
wim 21:9eb628d9e164 824 void TextLCD_Base::setAddress(int column, int row) {
wim 15:b70ebfffb258 825
wim 15:b70ebfffb258 826 // Sanity Check column
wim 15:b70ebfffb258 827 if (column < 0) {
wim 15:b70ebfffb258 828 _column = 0;
wim 15:b70ebfffb258 829 }
wim 15:b70ebfffb258 830 else if (column >= columns()) {
wim 15:b70ebfffb258 831 _column = columns() - 1;
wim 15:b70ebfffb258 832 } else _column = column;
wim 8:03116f75b66e 833
wim 15:b70ebfffb258 834 // Sanity Check row
wim 15:b70ebfffb258 835 if (row < 0) {
wim 15:b70ebfffb258 836 _row = 0;
wim 15:b70ebfffb258 837 }
wim 15:b70ebfffb258 838 else if (row >= rows()) {
wim 15:b70ebfffb258 839 _row = rows() - 1;
wim 15:b70ebfffb258 840 } else _row = row;
wim 15:b70ebfffb258 841
wim 15:b70ebfffb258 842
wim 15:b70ebfffb258 843 // Compute the memory address
wim 15:b70ebfffb258 844 // For LCD40x4: switch controllers if needed
wim 15:b70ebfffb258 845 // switch cursor if needed
wim 15:b70ebfffb258 846 int addr = getAddress(_column, _row);
wim 8:03116f75b66e 847
wim 13:24506ba22480 848 _writeCommand(0x80 | addr);
wim 8:03116f75b66e 849 }
simon 1:ac48b187213c 850
wim 29:a3663151aa65 851
wim 29:a3663151aa65 852 /** Return the number of columns
wim 29:a3663151aa65 853 *
wim 29:a3663151aa65 854 * @param return The number of columns
wim 29:a3663151aa65 855 */
wim 21:9eb628d9e164 856 int TextLCD_Base::columns() {
simon 1:ac48b187213c 857 switch (_type) {
wim 8:03116f75b66e 858 case LCD8x1:
wim 8:03116f75b66e 859 case LCD8x2:
wim 18:bd65dc10f27f 860 case LCD8x2B:
wim 8:03116f75b66e 861 return 8;
wim 15:b70ebfffb258 862
wim 15:b70ebfffb258 863 case LCD12x2:
wim 29:a3663151aa65 864 case LCD12x3B:
wim 15:b70ebfffb258 865 case LCD12x4:
wim 29:a3663151aa65 866 case LCD12x4B:
wim 15:b70ebfffb258 867 return 12;
wim 8:03116f75b66e 868
wim 13:24506ba22480 869 case LCD16x1:
simon 1:ac48b187213c 870 case LCD16x2:
simon 1:ac48b187213c 871 case LCD16x2B:
wim 28:30fa94f7341c 872 // case LCD16x3:
wim 8:03116f75b66e 873 case LCD16x4:
wim 8:03116f75b66e 874 return 16;
wim 8:03116f75b66e 875
wim 8:03116f75b66e 876 case LCD20x2:
wim 8:03116f75b66e 877 case LCD20x4:
wim 8:03116f75b66e 878 return 20;
wim 8:03116f75b66e 879
wim 29:a3663151aa65 880 case LCD24x1:
wim 8:03116f75b66e 881 case LCD24x2:
wim 29:a3663151aa65 882 case LCD24x4B:
wim 8:03116f75b66e 883 return 24;
wim 9:0893d986e717 884
wim 9:0893d986e717 885 case LCD40x2:
wim 15:b70ebfffb258 886 case LCD40x4:
wim 9:0893d986e717 887 return 40;
wim 8:03116f75b66e 888
wim 8:03116f75b66e 889 // Should never get here.
simon 1:ac48b187213c 890 default:
wim 8:03116f75b66e 891 return 0;
simon 1:ac48b187213c 892 }
simon 1:ac48b187213c 893 }
simon 1:ac48b187213c 894
wim 29:a3663151aa65 895 /** Return the number of rows
wim 29:a3663151aa65 896 *
wim 29:a3663151aa65 897 * @param return The number of rows
wim 29:a3663151aa65 898 */
wim 21:9eb628d9e164 899 int TextLCD_Base::rows() {
simon 1:ac48b187213c 900 switch (_type) {
wim 8:03116f75b66e 901 case LCD8x1:
wim 13:24506ba22480 902 case LCD16x1:
wim 29:a3663151aa65 903 case LCD24x1:
wim 8:03116f75b66e 904 return 1;
wim 8:03116f75b66e 905
wim 15:b70ebfffb258 906 case LCD8x2:
wim 18:bd65dc10f27f 907 case LCD8x2B:
wim 15:b70ebfffb258 908 case LCD12x2:
simon 1:ac48b187213c 909 case LCD16x2:
simon 1:ac48b187213c 910 case LCD16x2B:
simon 1:ac48b187213c 911 case LCD20x2:
wim 8:03116f75b66e 912 case LCD24x2:
wim 9:0893d986e717 913 case LCD40x2:
wim 8:03116f75b66e 914 return 2;
wim 28:30fa94f7341c 915
wim 29:a3663151aa65 916 case LCD12x3B:
wim 28:30fa94f7341c 917 // case LCD16x3:
wim 29:a3663151aa65 918 return 3;
wim 8:03116f75b66e 919
wim 15:b70ebfffb258 920 case LCD12x4:
wim 29:a3663151aa65 921 case LCD12x4B:
wim 8:03116f75b66e 922 case LCD16x4:
wim 8:03116f75b66e 923 case LCD20x4:
wim 29:a3663151aa65 924 case LCD24x4B:
wim 15:b70ebfffb258 925 case LCD40x4:
wim 8:03116f75b66e 926 return 4;
wim 12:6bf9d9957d31 927
wim 12:6bf9d9957d31 928 // Should never get here.
simon 1:ac48b187213c 929 default:
wim 8:03116f75b66e 930 return 0;
simon 1:ac48b187213c 931 }
simon 1:ac48b187213c 932 }
wim 10:dd9b3a696acd 933
wim 29:a3663151aa65 934 /** Set the Cursormode
wim 29:a3663151aa65 935 *
wim 29:a3663151aa65 936 * @param cursorMode The Cursor mode (CurOff_BlkOff, CurOn_BlkOff, CurOff_BlkOn, CurOn_BlkOn)
wim 29:a3663151aa65 937 */
wim 21:9eb628d9e164 938 void TextLCD_Base::setCursor(LCDCursor cursorMode) {
wim 15:b70ebfffb258 939
wim 17:652ab113bc2e 940 // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on
wim 17:652ab113bc2e 941 _currentCursor = cursorMode;
wim 10:dd9b3a696acd 942
wim 17:652ab113bc2e 943 // Configure only current LCD controller
wim 17:652ab113bc2e 944 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 15:b70ebfffb258 945
wim 15:b70ebfffb258 946 }
wim 15:b70ebfffb258 947
wim 29:a3663151aa65 948 /** Set the Displaymode
wim 29:a3663151aa65 949 *
wim 29:a3663151aa65 950 * @param displayMode The Display mode (DispOff, DispOn)
wim 29:a3663151aa65 951 */
wim 21:9eb628d9e164 952 void TextLCD_Base::setMode(LCDMode displayMode) {
wim 17:652ab113bc2e 953
wim 17:652ab113bc2e 954 // Save new displayMode, needed when 2 controllers are in use or when cursor is changed
wim 17:652ab113bc2e 955 _currentMode = displayMode;
wim 15:b70ebfffb258 956
wim 17:652ab113bc2e 957 // Select and configure second LCD controller when needed
wim 17:652ab113bc2e 958 if(_type==LCD40x4) {
wim 21:9eb628d9e164 959 if (_ctrl_idx==_LCDCtrl_0) {
wim 17:652ab113bc2e 960 // Configure primary LCD controller
wim 17:652ab113bc2e 961 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 11:9ec02df863a1 962
wim 17:652ab113bc2e 963 // Select 2nd controller
wim 21:9eb628d9e164 964 _ctrl_idx=_LCDCtrl_1;
wim 17:652ab113bc2e 965
wim 17:652ab113bc2e 966 // Configure secondary LCD controller
wim 21:9eb628d9e164 967 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 11:9ec02df863a1 968
wim 17:652ab113bc2e 969 // Restore current controller
wim 21:9eb628d9e164 970 _ctrl_idx=_LCDCtrl_0;
wim 17:652ab113bc2e 971 }
wim 17:652ab113bc2e 972 else {
wim 17:652ab113bc2e 973 // Select primary controller
wim 21:9eb628d9e164 974 _ctrl_idx=_LCDCtrl_0;
wim 17:652ab113bc2e 975
wim 17:652ab113bc2e 976 // Configure primary LCD controller
wim 21:9eb628d9e164 977 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 17:652ab113bc2e 978
wim 17:652ab113bc2e 979 // Restore current controller
wim 21:9eb628d9e164 980 _ctrl_idx=_LCDCtrl_1;
wim 11:9ec02df863a1 981
wim 17:652ab113bc2e 982 // Configure secondary LCD controller
wim 17:652ab113bc2e 983 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 11:9ec02df863a1 984
wim 10:dd9b3a696acd 985 }
wim 17:652ab113bc2e 986 }
wim 17:652ab113bc2e 987 else {
wim 17:652ab113bc2e 988 // Configure primary LCD controller
wim 17:652ab113bc2e 989 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 17:652ab113bc2e 990 }
wim 17:652ab113bc2e 991
wim 17:652ab113bc2e 992 }
wim 17:652ab113bc2e 993
wim 17:652ab113bc2e 994
wim 29:a3663151aa65 995 /** Low level method to restore the cursortype and display mode for current controller
wim 29:a3663151aa65 996 */
wim 21:9eb628d9e164 997 void TextLCD_Base::_setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType) {
wim 17:652ab113bc2e 998
wim 17:652ab113bc2e 999 // Configure current LCD controller
wim 17:652ab113bc2e 1000 _writeCommand(0x08 | displayMode | cursorType);
wim 10:dd9b3a696acd 1001 }
wim 10:dd9b3a696acd 1002
wim 29:a3663151aa65 1003
wim 29:a3663151aa65 1004 /** Set the Backlight mode
wim 29:a3663151aa65 1005 *
wim 29:a3663151aa65 1006 * @param backlightMode The Backlight mode (LightOff, LightOn)
wim 29:a3663151aa65 1007 */
wim 21:9eb628d9e164 1008 void TextLCD_Base::setBacklight(LCDBacklight backlightMode) {
wim 20:e0da005a777f 1009
wim 20:e0da005a777f 1010 if (backlightMode == LightOn) {
wim 21:9eb628d9e164 1011 this->_setBL(true);
wim 20:e0da005a777f 1012 }
wim 20:e0da005a777f 1013 else {
wim 21:9eb628d9e164 1014 this->_setBL(false);
wim 20:e0da005a777f 1015 }
wim 20:e0da005a777f 1016 }
wim 20:e0da005a777f 1017
wim 29:a3663151aa65 1018 /** Set User Defined Characters
wim 29:a3663151aa65 1019 *
wim 29:a3663151aa65 1020 * @param unsigned char c The Index of the UDC (0..7)
wim 29:a3663151aa65 1021 * @param char *udc_data The bitpatterns for the UDC (8 bytes of 5 significant bits)
wim 29:a3663151aa65 1022 */
wim 21:9eb628d9e164 1023 void TextLCD_Base::setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 1024
wim 15:b70ebfffb258 1025 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 1026 if(_type==LCD40x4) {
wim 19:c747b9e2e7b8 1027 _LCDCtrl_Idx current_ctrl_idx = _ctrl_idx; // Temp save current controller
wim 15:b70ebfffb258 1028
wim 15:b70ebfffb258 1029 // Select primary controller
wim 21:9eb628d9e164 1030 _ctrl_idx=_LCDCtrl_0;
wim 15:b70ebfffb258 1031
wim 15:b70ebfffb258 1032 // Configure primary LCD controller
wim 15:b70ebfffb258 1033 _setUDC(c, udc_data);
wim 15:b70ebfffb258 1034
wim 15:b70ebfffb258 1035 // Select 2nd controller
wim 21:9eb628d9e164 1036 _ctrl_idx=_LCDCtrl_1;
wim 15:b70ebfffb258 1037
wim 15:b70ebfffb258 1038 // Configure secondary LCD controller
wim 15:b70ebfffb258 1039 _setUDC(c, udc_data);
wim 11:9ec02df863a1 1040
wim 15:b70ebfffb258 1041 // Restore current controller
wim 19:c747b9e2e7b8 1042 _ctrl_idx=current_ctrl_idx;
wim 15:b70ebfffb258 1043 }
wim 15:b70ebfffb258 1044 else {
wim 15:b70ebfffb258 1045 // Configure primary LCD controller
wim 15:b70ebfffb258 1046 _setUDC(c, udc_data);
wim 15:b70ebfffb258 1047 }
wim 15:b70ebfffb258 1048
wim 15:b70ebfffb258 1049 }
wim 15:b70ebfffb258 1050
wim 29:a3663151aa65 1051 /** Low level method to store user defined characters for current controller
wim 29:a3663151aa65 1052 */
wim 21:9eb628d9e164 1053 void TextLCD_Base::_setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 1054
wim 15:b70ebfffb258 1055 // Select CG RAM for current LCD controller
wim 15:b70ebfffb258 1056 _writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address,
wim 15:b70ebfffb258 1057 //8 sequential locations needed per UDC
wim 15:b70ebfffb258 1058 // Store UDC pattern
wim 11:9ec02df863a1 1059 for (int i=0; i<8; i++) {
wim 13:24506ba22480 1060 _writeData(*udc_data++);
wim 11:9ec02df863a1 1061 }
wim 15:b70ebfffb258 1062
wim 15:b70ebfffb258 1063 //Select DD RAM again for current LCD controller
wim 15:b70ebfffb258 1064 int addr = getAddress(_column, _row);
wim 15:b70ebfffb258 1065 _writeCommand(0x80 | addr);
wim 15:b70ebfffb258 1066
wim 11:9ec02df863a1 1067 }
wim 21:9eb628d9e164 1068
wim 23:d47f226efb24 1069 //--------- End TextLCD_Base -----------
wim 21:9eb628d9e164 1070
wim 22:35742ec80c24 1071
wim 21:9eb628d9e164 1072
wim 23:d47f226efb24 1073 //--------- Start TextLCD Bus -----------
wim 21:9eb628d9e164 1074
wim 21:9eb628d9e164 1075 /* Create a TextLCD interface for using regular mbed pins
wim 21:9eb628d9e164 1076 *
wim 21:9eb628d9e164 1077 * @param rs Instruction/data control line
wim 21:9eb628d9e164 1078 * @param e Enable line (clock)
wim 21:9eb628d9e164 1079 * @param d4-d7 Data lines for using as a 4-bit interface
wim 21:9eb628d9e164 1080 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 21:9eb628d9e164 1081 * @param bl Backlight control line (optional, default = NC)
wim 21:9eb628d9e164 1082 * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
wim 21:9eb628d9e164 1083 * @param ctrl LCD controller (default = HD44780)
wim 21:9eb628d9e164 1084 */
wim 21:9eb628d9e164 1085 TextLCD::TextLCD(PinName rs, PinName e,
wim 21:9eb628d9e164 1086 PinName d4, PinName d5, PinName d6, PinName d7,
wim 21:9eb628d9e164 1087 LCDType type, PinName bl, PinName e2, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1088 TextLCD_Base(type, ctrl),
wim 22:35742ec80c24 1089 _rs(rs), _e(e), _d(d4, d5, d6, d7) {
wim 22:35742ec80c24 1090
wim 22:35742ec80c24 1091 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 22:35742ec80c24 1092 if (bl != NC) {
wim 22:35742ec80c24 1093 _bl = new DigitalOut(bl); //Construct new pin
wim 22:35742ec80c24 1094 _bl->write(0); //Deactivate
wim 22:35742ec80c24 1095 }
wim 22:35742ec80c24 1096 else {
wim 22:35742ec80c24 1097 // No Hardware Backlight pin
wim 22:35742ec80c24 1098 _bl = NULL; //Construct dummy pin
wim 22:35742ec80c24 1099 }
wim 22:35742ec80c24 1100
wim 22:35742ec80c24 1101 // The hardware Enable2 pin is only needed for LCD40x4. Test and make sure whether it exists or not to prevent illegal access.
wim 22:35742ec80c24 1102 if (e2 != NC) {
wim 22:35742ec80c24 1103 _e2 = new DigitalOut(e2); //Construct new pin
wim 22:35742ec80c24 1104 _e2->write(0); //Deactivate
wim 22:35742ec80c24 1105 }
wim 22:35742ec80c24 1106 else {
wim 22:35742ec80c24 1107 // No Hardware Enable pin
wim 22:35742ec80c24 1108 _e2 = NULL; //Construct dummy pin
wim 22:35742ec80c24 1109 }
wim 21:9eb628d9e164 1110
wim 21:9eb628d9e164 1111 _init();
wim 21:9eb628d9e164 1112
wim 21:9eb628d9e164 1113 }
wim 21:9eb628d9e164 1114
wim 29:a3663151aa65 1115
wim 29:a3663151aa65 1116 /** Destruct a TextLCD interface for using regular mbed pins
wim 29:a3663151aa65 1117 *
wim 29:a3663151aa65 1118 * @param none
wim 29:a3663151aa65 1119 * @return none
wim 29:a3663151aa65 1120 */
wim 29:a3663151aa65 1121 TextLCD::~TextLCD() {
wim 29:a3663151aa65 1122 if (_bl != NULL) {delete _bl;} // BL pin
wim 29:a3663151aa65 1123 if (_e2 != NULL) {delete _e2;} // E2 pin
wim 29:a3663151aa65 1124 }
wim 29:a3663151aa65 1125
wim 29:a3663151aa65 1126
wim 22:35742ec80c24 1127 /** Set E pin (or E2 pin)
wim 22:35742ec80c24 1128 * Used for mbed pins, I2C bus expander or SPI shiftregister
wim 22:35742ec80c24 1129 * Default PinName value for E2 is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
wim 22:35742ec80c24 1130 * @param value true or false
wim 22:35742ec80c24 1131 * @return none
wim 22:35742ec80c24 1132 */
wim 21:9eb628d9e164 1133 void TextLCD::_setEnable(bool value) {
wim 21:9eb628d9e164 1134
wim 22:35742ec80c24 1135 if(_ctrl_idx==_LCDCtrl_0) {
wim 22:35742ec80c24 1136 if (value) {
wim 22:35742ec80c24 1137 _e = 1; // Set E bit
wim 22:35742ec80c24 1138 }
wim 22:35742ec80c24 1139 else {
wim 22:35742ec80c24 1140 _e = 0; // Reset E bit
wim 22:35742ec80c24 1141 }
wim 22:35742ec80c24 1142 }
wim 22:35742ec80c24 1143 else {
wim 22:35742ec80c24 1144 if (value) {
wim 22:35742ec80c24 1145 if (_e2 != NULL) {_e2->write(1);} //Set E2 bit
wim 22:35742ec80c24 1146 }
wim 22:35742ec80c24 1147 else {
wim 22:35742ec80c24 1148 if (_e2 != NULL) {_e2->write(0);} //Reset E2 bit
wim 22:35742ec80c24 1149 }
wim 22:35742ec80c24 1150 }
wim 21:9eb628d9e164 1151
wim 21:9eb628d9e164 1152 }
wim 21:9eb628d9e164 1153
wim 21:9eb628d9e164 1154 // Set RS pin
wim 21:9eb628d9e164 1155 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1156 void TextLCD::_setRS(bool value) {
wim 21:9eb628d9e164 1157
wim 22:35742ec80c24 1158 if (value) {
wim 21:9eb628d9e164 1159 _rs = 1; // Set RS bit
wim 22:35742ec80c24 1160 }
wim 22:35742ec80c24 1161 else {
wim 21:9eb628d9e164 1162 _rs = 0; // Reset RS bit
wim 22:35742ec80c24 1163 }
wim 21:9eb628d9e164 1164
wim 21:9eb628d9e164 1165 }
wim 21:9eb628d9e164 1166
wim 22:35742ec80c24 1167 /** Set BL pin
wim 22:35742ec80c24 1168 * Used for mbed pins, I2C bus expander or SPI shiftregister
wim 22:35742ec80c24 1169 * Default PinName value is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
wim 22:35742ec80c24 1170 * @param value true or false
wim 22:35742ec80c24 1171 * @return none
wim 22:35742ec80c24 1172 */
wim 21:9eb628d9e164 1173 void TextLCD::_setBL(bool value) {
wim 21:9eb628d9e164 1174
wim 22:35742ec80c24 1175 if (value) {
wim 22:35742ec80c24 1176 if (_bl != NULL) {_bl->write(1);} //Set BL bit
wim 22:35742ec80c24 1177 }
wim 22:35742ec80c24 1178 else {
wim 22:35742ec80c24 1179 if (_bl != NULL) {_bl->write(0);} //Reset BL bit
wim 22:35742ec80c24 1180 }
wim 21:9eb628d9e164 1181
wim 21:9eb628d9e164 1182 }
wim 21:9eb628d9e164 1183
wim 21:9eb628d9e164 1184 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1185 // Used for mbed pins, I2C bus expander or SPI shifregister
wim 21:9eb628d9e164 1186 void TextLCD::_setData(int value) {
wim 21:9eb628d9e164 1187 _d = value & 0x0F; // Write Databits
wim 21:9eb628d9e164 1188 }
wim 21:9eb628d9e164 1189
wim 22:35742ec80c24 1190
wim 23:d47f226efb24 1191 //----------- End TextLCD ---------------
wim 21:9eb628d9e164 1192
wim 21:9eb628d9e164 1193
wim 23:d47f226efb24 1194 //--------- Start TextLCD_I2C -----------
wim 22:35742ec80c24 1195
wim 26:bd897a001012 1196 /** Create a TextLCD interface using an I2C PC8574 (or PCF8574A) or MCP23008 portexpander
wim 22:35742ec80c24 1197 *
wim 22:35742ec80c24 1198 * @param i2c I2C Bus
wim 26:bd897a001012 1199 * @param deviceAddress I2C slave address (PCF8574, PCF8574A or MCP23008, default = 0x40)
wim 22:35742ec80c24 1200 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 22:35742ec80c24 1201 * @param ctrl LCD controller (default = HD44780)
wim 22:35742ec80c24 1202 */
wim 21:9eb628d9e164 1203 TextLCD_I2C::TextLCD_I2C(I2C *i2c, char deviceAddress, LCDType type, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1204 TextLCD_Base(type, ctrl),
wim 21:9eb628d9e164 1205 _i2c(i2c){
wim 21:9eb628d9e164 1206
wim 22:35742ec80c24 1207 _slaveAddress = deviceAddress & 0xFE;
wim 28:30fa94f7341c 1208
wim 28:30fa94f7341c 1209
wim 28:30fa94f7341c 1210 // Setup the I2C bus
wim 28:30fa94f7341c 1211 // The max bitrate for PCF8574 is 100kbit, the max bitrate for MCP23008 is 400kbit,
wim 28:30fa94f7341c 1212 // _i2c->frequency(100000);
wim 21:9eb628d9e164 1213
wim 26:bd897a001012 1214
wim 26:bd897a001012 1215 #if (MCP23008==1)
wim 26:bd897a001012 1216 // MCP23008 portexpander Init
wim 27:22d5086f6ba6 1217 _write_register(IODIR, 0x00); // All outputs
wim 27:22d5086f6ba6 1218 _write_register(IPOL, 0x00); // No reverse polarity
wim 27:22d5086f6ba6 1219 _write_register(GPINTEN, 0x00); // No interrupt
wim 27:22d5086f6ba6 1220 _write_register(DEFVAL, 0x00); // Default value to compare against for interrupts
wim 27:22d5086f6ba6 1221 _write_register(INTCON, 0x00); // No interrupt on changes
wim 27:22d5086f6ba6 1222 _write_register(IOCON, 0x00); // Interrupt polarity
wim 27:22d5086f6ba6 1223 _write_register(GPPU, 0x00); // No Pullup
wim 27:22d5086f6ba6 1224 _write_register(INTF, 0x00); //
wim 27:22d5086f6ba6 1225 _write_register(INTCAP, 0x00); //
wim 27:22d5086f6ba6 1226 _write_register(GPIO, 0x00); // Output/Input pins
wim 27:22d5086f6ba6 1227 _write_register(OLAT, 0x00); // Output Latch
wim 26:bd897a001012 1228
wim 21:9eb628d9e164 1229 // Init the portexpander bus
wim 21:9eb628d9e164 1230 _lcd_bus = D_LCD_BUS_DEF;
wim 21:9eb628d9e164 1231
wim 21:9eb628d9e164 1232 // write the new data to the portexpander
wim 26:bd897a001012 1233 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1234 #else
wim 26:bd897a001012 1235 // PCF8574 of PCF8574A portexpander
wim 26:bd897a001012 1236
wim 26:bd897a001012 1237 // Init the portexpander bus
wim 26:bd897a001012 1238 _lcd_bus = D_LCD_BUS_DEF;
wim 26:bd897a001012 1239
wim 26:bd897a001012 1240 // write the new data to the portexpander
wim 21:9eb628d9e164 1241 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1242 #endif
wim 21:9eb628d9e164 1243
wim 21:9eb628d9e164 1244 _init();
wim 21:9eb628d9e164 1245
wim 21:9eb628d9e164 1246 }
wim 21:9eb628d9e164 1247
wim 21:9eb628d9e164 1248 // Set E pin (or E2 pin)
wim 21:9eb628d9e164 1249 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1250 void TextLCD_I2C::_setEnable(bool value) {
wim 21:9eb628d9e164 1251
wim 22:35742ec80c24 1252 if(_ctrl_idx==_LCDCtrl_0) {
wim 26:bd897a001012 1253 if (value) {
wim 22:35742ec80c24 1254 _lcd_bus |= D_LCD_E; // Set E bit
wim 26:bd897a001012 1255 }
wim 26:bd897a001012 1256 else {
wim 22:35742ec80c24 1257 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 26:bd897a001012 1258 }
wim 22:35742ec80c24 1259 }
wim 22:35742ec80c24 1260 else {
wim 26:bd897a001012 1261 if (value) {
wim 22:35742ec80c24 1262 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 26:bd897a001012 1263 }
wim 26:bd897a001012 1264 else {
wim 22:35742ec80c24 1265 _lcd_bus &= ~D_LCD_E2; // Reset E2bit
wim 26:bd897a001012 1266 }
wim 26:bd897a001012 1267 }
wim 26:bd897a001012 1268
wim 26:bd897a001012 1269
wim 26:bd897a001012 1270 #if (MCP23008==1)
wim 26:bd897a001012 1271 // MCP23008 portexpander
wim 26:bd897a001012 1272
wim 26:bd897a001012 1273 // write the new data to the portexpander
wim 26:bd897a001012 1274 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1275 #else
wim 26:bd897a001012 1276 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1277
wim 22:35742ec80c24 1278 // write the new data to the I2C portexpander
wim 22:35742ec80c24 1279 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1280 #endif
wim 21:9eb628d9e164 1281 }
wim 21:9eb628d9e164 1282
wim 21:9eb628d9e164 1283 // Set RS pin
wim 21:9eb628d9e164 1284 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1285 void TextLCD_I2C::_setRS(bool value) {
wim 21:9eb628d9e164 1286
wim 26:bd897a001012 1287 if (value) {
wim 22:35742ec80c24 1288 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 26:bd897a001012 1289 }
wim 26:bd897a001012 1290 else {
wim 22:35742ec80c24 1291 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 26:bd897a001012 1292 }
wim 26:bd897a001012 1293
wim 26:bd897a001012 1294
wim 26:bd897a001012 1295 #if (MCP23008==1)
wim 26:bd897a001012 1296 // MCP23008 portexpander
wim 26:bd897a001012 1297
wim 26:bd897a001012 1298 // write the new data to the portexpander
wim 26:bd897a001012 1299 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1300 #else
wim 26:bd897a001012 1301 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1302
wim 22:35742ec80c24 1303 // write the new data to the I2C portexpander
wim 22:35742ec80c24 1304 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1305 #endif
wim 21:9eb628d9e164 1306
wim 21:9eb628d9e164 1307 }
wim 21:9eb628d9e164 1308
wim 21:9eb628d9e164 1309 // Set BL pin
wim 21:9eb628d9e164 1310 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1311 void TextLCD_I2C::_setBL(bool value) {
wim 21:9eb628d9e164 1312
wim 26:bd897a001012 1313 if (value) {
wim 21:9eb628d9e164 1314 _lcd_bus |= D_LCD_BL; // Set BL bit
wim 26:bd897a001012 1315 }
wim 26:bd897a001012 1316 else {
wim 21:9eb628d9e164 1317 _lcd_bus &= ~D_LCD_BL; // Reset BL bit
wim 26:bd897a001012 1318 }
wim 26:bd897a001012 1319
wim 26:bd897a001012 1320 #if (MCP23008==1)
wim 26:bd897a001012 1321 // MCP23008 portexpander
wim 26:bd897a001012 1322
wim 26:bd897a001012 1323 // write the new data to the portexpander
wim 26:bd897a001012 1324 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1325 #else
wim 26:bd897a001012 1326 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1327
wim 21:9eb628d9e164 1328 // write the new data to the I2C portexpander
wim 21:9eb628d9e164 1329 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1330 #endif
wim 21:9eb628d9e164 1331
wim 21:9eb628d9e164 1332 }
wim 21:9eb628d9e164 1333
wim 21:9eb628d9e164 1334
wim 21:9eb628d9e164 1335
wim 21:9eb628d9e164 1336 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1337 // Used for mbed pins, I2C bus expander or SPI shifregister
wim 21:9eb628d9e164 1338 void TextLCD_I2C::_setData(int value) {
wim 21:9eb628d9e164 1339 int data;
wim 22:35742ec80c24 1340
wim 22:35742ec80c24 1341 // Set bit by bit to support any mapping of expander portpins to LCD pins
wim 21:9eb628d9e164 1342
wim 22:35742ec80c24 1343 data = value & 0x0F;
wim 26:bd897a001012 1344 if (data & 0x01){
wim 22:35742ec80c24 1345 _lcd_bus |= D_LCD_D4; // Set Databit
wim 26:bd897a001012 1346 }
wim 26:bd897a001012 1347 else {
wim 26:bd897a001012 1348 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 26:bd897a001012 1349 }
wim 21:9eb628d9e164 1350
wim 26:bd897a001012 1351 if (data & 0x02){
wim 22:35742ec80c24 1352 _lcd_bus |= D_LCD_D5; // Set Databit
wim 26:bd897a001012 1353 }
wim 26:bd897a001012 1354 else {
wim 26:bd897a001012 1355 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 26:bd897a001012 1356 }
wim 21:9eb628d9e164 1357
wim 26:bd897a001012 1358 if (data & 0x04) {
wim 22:35742ec80c24 1359 _lcd_bus |= D_LCD_D6; // Set Databit
wim 26:bd897a001012 1360 }
wim 26:bd897a001012 1361 else {
wim 26:bd897a001012 1362 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 26:bd897a001012 1363 }
wim 21:9eb628d9e164 1364
wim 26:bd897a001012 1365 if (data & 0x08) {
wim 22:35742ec80c24 1366 _lcd_bus |= D_LCD_D7; // Set Databit
wim 26:bd897a001012 1367 }
wim 26:bd897a001012 1368 else {
wim 26:bd897a001012 1369 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 26:bd897a001012 1370 }
wim 21:9eb628d9e164 1371
wim 26:bd897a001012 1372 #if (MCP23008==1)
wim 26:bd897a001012 1373 // MCP23008 portexpander
wim 26:bd897a001012 1374
wim 26:bd897a001012 1375 // write the new data to the portexpander
wim 26:bd897a001012 1376 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1377 #else
wim 26:bd897a001012 1378 // PCF8574 of PCF8574A portexpander
wim 26:bd897a001012 1379
wim 22:35742ec80c24 1380 // write the new data to the I2C portexpander
wim 26:bd897a001012 1381 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1382 #endif
wim 22:35742ec80c24 1383
wim 22:35742ec80c24 1384 }
wim 21:9eb628d9e164 1385
wim 26:bd897a001012 1386 // Write data to MCP23008 I2C portexpander
wim 26:bd897a001012 1387 void TextLCD_I2C::_write_register (int reg, int value) {
wim 26:bd897a001012 1388 char data[] = {reg, value};
wim 26:bd897a001012 1389
wim 26:bd897a001012 1390 _i2c->write(_slaveAddress, data, 2);
wim 26:bd897a001012 1391
wim 26:bd897a001012 1392 }
wim 26:bd897a001012 1393
wim 23:d47f226efb24 1394 //---------- End TextLCD_I2C ------------
wim 21:9eb628d9e164 1395
wim 21:9eb628d9e164 1396
wim 28:30fa94f7341c 1397 //--------- Start TextLCD_I2C_N ---------
wim 28:30fa94f7341c 1398
wim 28:30fa94f7341c 1399 /** Create a TextLCD interface using a controller with native I2C interface
wim 28:30fa94f7341c 1400 *
wim 28:30fa94f7341c 1401 * @param i2c I2C Bus
wim 28:30fa94f7341c 1402 * @param deviceAddress I2C slave address (default = 0x7C)
wim 28:30fa94f7341c 1403 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 28:30fa94f7341c 1404 * @param bl Backlight control line (optional, default = NC)
wim 28:30fa94f7341c 1405 * @param ctrl LCD controller (default = ST7032_3V3)
wim 28:30fa94f7341c 1406 */
wim 28:30fa94f7341c 1407 TextLCD_I2C_N::TextLCD_I2C_N(I2C *i2c, char deviceAddress, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 28:30fa94f7341c 1408 TextLCD_Base(type, ctrl),
wim 28:30fa94f7341c 1409 _i2c(i2c){
wim 28:30fa94f7341c 1410
wim 28:30fa94f7341c 1411 _slaveAddress = deviceAddress & 0xFE;
wim 28:30fa94f7341c 1412
wim 28:30fa94f7341c 1413 // Setup the I2C bus
wim 29:a3663151aa65 1414 // The max bitrate for ST7032i is 400kbit, lets stick to default here
wim 29:a3663151aa65 1415 _i2c->frequency(100000);
wim 29:a3663151aa65 1416 // _i2c->frequency(50000);
wim 28:30fa94f7341c 1417
wim 28:30fa94f7341c 1418
wim 28:30fa94f7341c 1419 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 28:30fa94f7341c 1420 if (bl != NC) {
wim 28:30fa94f7341c 1421 _bl = new DigitalOut(bl); //Construct new pin
wim 28:30fa94f7341c 1422 _bl->write(0); //Deactivate
wim 28:30fa94f7341c 1423 }
wim 28:30fa94f7341c 1424 else {
wim 28:30fa94f7341c 1425 // No Hardware Backlight pin
wim 28:30fa94f7341c 1426 _bl = NULL; //Construct dummy pin
wim 28:30fa94f7341c 1427 }
wim 28:30fa94f7341c 1428
wim 28:30fa94f7341c 1429 _init();
wim 28:30fa94f7341c 1430 }
wim 28:30fa94f7341c 1431
wim 28:30fa94f7341c 1432 TextLCD_I2C_N::~TextLCD_I2C_N() {
wim 28:30fa94f7341c 1433 if (_bl != NULL) {delete _bl;} // BL pin
wim 28:30fa94f7341c 1434 }
wim 28:30fa94f7341c 1435
wim 28:30fa94f7341c 1436 // Not used in this mode
wim 28:30fa94f7341c 1437 void TextLCD_I2C_N::_setEnable(bool value) {
wim 28:30fa94f7341c 1438 }
wim 28:30fa94f7341c 1439
wim 28:30fa94f7341c 1440 // Set RS pin
wim 28:30fa94f7341c 1441 // Used for mbed pins, I2C bus expander or SPI shiftregister and native I2C or SPI
wim 28:30fa94f7341c 1442 void TextLCD_I2C_N::_setRS(bool value) {
wim 28:30fa94f7341c 1443
wim 28:30fa94f7341c 1444 if (value) {
wim 28:30fa94f7341c 1445 _controlbyte = 0x40; // Next byte is data, No more control bytes will follow
wim 28:30fa94f7341c 1446 }
wim 28:30fa94f7341c 1447 else {
wim 28:30fa94f7341c 1448 _controlbyte = 0x00; // Next byte is command, No more control bytes will follow
wim 28:30fa94f7341c 1449 }
wim 28:30fa94f7341c 1450 }
wim 28:30fa94f7341c 1451
wim 28:30fa94f7341c 1452 // Set BL pin
wim 28:30fa94f7341c 1453 void TextLCD_I2C_N::_setBL(bool value) {
wim 28:30fa94f7341c 1454 if (_bl) {
wim 28:30fa94f7341c 1455 _bl->write(value);
wim 28:30fa94f7341c 1456 }
wim 28:30fa94f7341c 1457 }
wim 28:30fa94f7341c 1458
wim 29:a3663151aa65 1459
wim 29:a3663151aa65 1460 // Not used in this mode
wim 29:a3663151aa65 1461 void TextLCD_I2C_N::_setData(int value) {
wim 29:a3663151aa65 1462 }
wim 29:a3663151aa65 1463
wim 29:a3663151aa65 1464
wim 28:30fa94f7341c 1465 // Write a byte using I2C
wim 28:30fa94f7341c 1466 void TextLCD_I2C_N::_writeByte(int value) {
wim 28:30fa94f7341c 1467
wim 28:30fa94f7341c 1468 char data[] = {_controlbyte, value};
wim 28:30fa94f7341c 1469
wim 28:30fa94f7341c 1470 _i2c->write(_slaveAddress, data, 2);
wim 28:30fa94f7341c 1471
wim 28:30fa94f7341c 1472 }
wim 28:30fa94f7341c 1473
wim 28:30fa94f7341c 1474
wim 28:30fa94f7341c 1475 //-------- End TextLCD_I2C_N ------------
wim 28:30fa94f7341c 1476
wim 28:30fa94f7341c 1477
wim 28:30fa94f7341c 1478
wim 21:9eb628d9e164 1479
wim 23:d47f226efb24 1480 //--------- Start TextLCD_SPI -----------
wim 21:9eb628d9e164 1481
wim 22:35742ec80c24 1482 /** Create a TextLCD interface using an SPI 74595 portexpander
wim 22:35742ec80c24 1483 *
wim 22:35742ec80c24 1484 * @param spi SPI Bus
wim 22:35742ec80c24 1485 * @param cs chip select pin (active low)
wim 22:35742ec80c24 1486 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 22:35742ec80c24 1487 * @param ctrl LCD controller (default = HD44780)
wim 22:35742ec80c24 1488 */
wim 21:9eb628d9e164 1489 TextLCD_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1490 TextLCD_Base(type, ctrl),
wim 21:9eb628d9e164 1491 _spi(spi),
wim 21:9eb628d9e164 1492 _cs(cs) {
wim 21:9eb628d9e164 1493
wim 21:9eb628d9e164 1494 // Setup the spi for 8 bit data, low steady state clock,
wim 21:9eb628d9e164 1495 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 21:9eb628d9e164 1496 _spi->format(8,0);
wim 21:9eb628d9e164 1497 _spi->frequency(500000);
wim 21:9eb628d9e164 1498 //_spi.frequency(1000000);
wim 21:9eb628d9e164 1499
wim 21:9eb628d9e164 1500
wim 21:9eb628d9e164 1501 // Init the portexpander bus
wim 21:9eb628d9e164 1502 _lcd_bus = D_LCD_BUS_DEF;
wim 21:9eb628d9e164 1503
wim 21:9eb628d9e164 1504 // write the new data to the portexpander
wim 21:9eb628d9e164 1505 _setCS(false);
wim 21:9eb628d9e164 1506 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 1507 _setCS(true);
wim 21:9eb628d9e164 1508
wim 21:9eb628d9e164 1509 _init();
wim 21:9eb628d9e164 1510
wim 21:9eb628d9e164 1511 }
wim 21:9eb628d9e164 1512
wim 21:9eb628d9e164 1513 // Set E pin (or E2 pin)
wim 21:9eb628d9e164 1514 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1515 void TextLCD_SPI::_setEnable(bool value) {
wim 21:9eb628d9e164 1516
wim 22:35742ec80c24 1517 if(_ctrl_idx==_LCDCtrl_0) {
wim 26:bd897a001012 1518 if (value) {
wim 22:35742ec80c24 1519 _lcd_bus |= D_LCD_E; // Set E bit
wim 26:bd897a001012 1520 }
wim 26:bd897a001012 1521 else {
wim 22:35742ec80c24 1522 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 26:bd897a001012 1523 }
wim 22:35742ec80c24 1524 }
wim 22:35742ec80c24 1525 else {
wim 26:bd897a001012 1526 if (value) {
wim 22:35742ec80c24 1527 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 26:bd897a001012 1528 }
wim 26:bd897a001012 1529 else {
wim 22:35742ec80c24 1530 _lcd_bus &= ~D_LCD_E2; // Reset E2 bit
wim 26:bd897a001012 1531 }
wim 22:35742ec80c24 1532 }
wim 21:9eb628d9e164 1533
wim 22:35742ec80c24 1534 // write the new data to the SPI portexpander
wim 22:35742ec80c24 1535 _setCS(false);
wim 22:35742ec80c24 1536 _spi->write(_lcd_bus);
wim 22:35742ec80c24 1537 _setCS(true);
wim 21:9eb628d9e164 1538
wim 21:9eb628d9e164 1539 }
wim 21:9eb628d9e164 1540
wim 21:9eb628d9e164 1541 // Set RS pin
wim 21:9eb628d9e164 1542 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1543 void TextLCD_SPI::_setRS(bool value) {
wim 21:9eb628d9e164 1544
wim 22:35742ec80c24 1545 if (value) {
wim 21:9eb628d9e164 1546 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 22:35742ec80c24 1547 }
wim 22:35742ec80c24 1548 else {
wim 21:9eb628d9e164 1549 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 22:35742ec80c24 1550 }
wim 21:9eb628d9e164 1551
wim 21:9eb628d9e164 1552 // write the new data to the SPI portexpander
wim 21:9eb628d9e164 1553 _setCS(false);
wim 21:9eb628d9e164 1554 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 1555 _setCS(true);
wim 21:9eb628d9e164 1556
wim 21:9eb628d9e164 1557 }
wim 21:9eb628d9e164 1558
wim 21:9eb628d9e164 1559 // Set BL pin
wim 21:9eb628d9e164 1560 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1561 void TextLCD_SPI::_setBL(bool value) {
wim 21:9eb628d9e164 1562
wim 22:35742ec80c24 1563 if (value) {
wim 21:9eb628d9e164 1564 _lcd_bus |= D_LCD_BL; // Set BL bit
wim 22:35742ec80c24 1565 }
wim 22:35742ec80c24 1566 else {
wim 21:9eb628d9e164 1567 _lcd_bus &= ~D_LCD_BL; // Reset BL bit
wim 22:35742ec80c24 1568 }
wim 21:9eb628d9e164 1569
wim 21:9eb628d9e164 1570 // write the new data to the SPI portexpander
wim 21:9eb628d9e164 1571 _setCS(false);
wim 21:9eb628d9e164 1572 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 1573 _setCS(true);
wim 21:9eb628d9e164 1574
wim 21:9eb628d9e164 1575 }
wim 21:9eb628d9e164 1576
wim 21:9eb628d9e164 1577
wim 21:9eb628d9e164 1578 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1579 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1580 void TextLCD_SPI::_setData(int value) {
wim 21:9eb628d9e164 1581 int data;
wim 21:9eb628d9e164 1582
wim 22:35742ec80c24 1583 // Set bit by bit to support any mapping of expander portpins to LCD pins
wim 22:35742ec80c24 1584
wim 22:35742ec80c24 1585 data = value & 0x0F;
wim 26:bd897a001012 1586 if (data & 0x01) {
wim 22:35742ec80c24 1587 _lcd_bus |= D_LCD_D4; // Set Databit
wim 26:bd897a001012 1588 }
wim 26:bd897a001012 1589 else {
wim 22:35742ec80c24 1590 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 26:bd897a001012 1591 }
wim 26:bd897a001012 1592
wim 26:bd897a001012 1593 if (data & 0x02) {
wim 22:35742ec80c24 1594 _lcd_bus |= D_LCD_D5; // Set Databit
wim 26:bd897a001012 1595 }
wim 26:bd897a001012 1596 else {
wim 22:35742ec80c24 1597 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 26:bd897a001012 1598 }
wim 26:bd897a001012 1599
wim 26:bd897a001012 1600 if (data & 0x04) {
wim 22:35742ec80c24 1601 _lcd_bus |= D_LCD_D6; // Set Databit
wim 26:bd897a001012 1602 }
wim 26:bd897a001012 1603 else {
wim 22:35742ec80c24 1604 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 26:bd897a001012 1605 }
wim 26:bd897a001012 1606
wim 26:bd897a001012 1607 if (data & 0x08) {
wim 22:35742ec80c24 1608 _lcd_bus |= D_LCD_D7; // Set Databit
wim 26:bd897a001012 1609 }
wim 26:bd897a001012 1610 else {
wim 26:bd897a001012 1611 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 26:bd897a001012 1612 }
wim 21:9eb628d9e164 1613
wim 22:35742ec80c24 1614 // write the new data to the SPI portexpander
wim 22:35742ec80c24 1615 _setCS(false);
wim 22:35742ec80c24 1616 _spi->write(_lcd_bus);
wim 22:35742ec80c24 1617 _setCS(true);
wim 21:9eb628d9e164 1618
wim 21:9eb628d9e164 1619 }
wim 21:9eb628d9e164 1620
wim 21:9eb628d9e164 1621
wim 21:9eb628d9e164 1622 // Set CS line.
wim 21:9eb628d9e164 1623 // Only used for SPI bus
wim 21:9eb628d9e164 1624 void TextLCD_SPI::_setCS(bool value) {
wim 21:9eb628d9e164 1625
wim 21:9eb628d9e164 1626 if (value) {
wim 21:9eb628d9e164 1627 _cs = 1; // Set CS pin
wim 21:9eb628d9e164 1628 }
wim 22:35742ec80c24 1629 else {
wim 21:9eb628d9e164 1630 _cs = 0; // Reset CS pin
wim 22:35742ec80c24 1631 }
wim 21:9eb628d9e164 1632 }
wim 21:9eb628d9e164 1633
wim 23:d47f226efb24 1634 //---------- End TextLCD_SPI ------------
wim 22:35742ec80c24 1635
wim 22:35742ec80c24 1636
wim 25:6162b31128c9 1637 //--------- Start TextLCD_SPI_N ---------
Sissors 24:fb3399713710 1638
wim 25:6162b31128c9 1639 /** Create a TextLCD interface using a controller with a native SPI interface
Sissors 24:fb3399713710 1640 *
Sissors 24:fb3399713710 1641 * @param spi SPI Bus
Sissors 24:fb3399713710 1642 * @param cs chip select pin (active low)
wim 25:6162b31128c9 1643 * @param rs Instruction/data control line
Sissors 24:fb3399713710 1644 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 25:6162b31128c9 1645 * @param bl Backlight control line (optional, default = NC)
wim 26:bd897a001012 1646 * @param ctrl LCD controller (default = ST7032_3V3)
wim 25:6162b31128c9 1647 */
wim 25:6162b31128c9 1648 TextLCD_SPI_N::TextLCD_SPI_N(SPI *spi, PinName cs, PinName rs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 25:6162b31128c9 1649 TextLCD_Base(type, ctrl),
wim 25:6162b31128c9 1650 _spi(spi),
wim 25:6162b31128c9 1651 _cs(cs),
wim 25:6162b31128c9 1652 _rs(rs) {
Sissors 24:fb3399713710 1653
Sissors 24:fb3399713710 1654 // Setup the spi for 8 bit data, low steady state clock,
Sissors 24:fb3399713710 1655 // rising edge capture, with a 500KHz or 1MHz clock rate
Sissors 24:fb3399713710 1656 _spi->format(8,0);
Sissors 24:fb3399713710 1657 _spi->frequency(1000000);
Sissors 24:fb3399713710 1658
Sissors 24:fb3399713710 1659 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
Sissors 24:fb3399713710 1660 if (bl != NC) {
Sissors 24:fb3399713710 1661 _bl = new DigitalOut(bl); //Construct new pin
Sissors 24:fb3399713710 1662 _bl->write(0); //Deactivate
Sissors 24:fb3399713710 1663 }
Sissors 24:fb3399713710 1664 else {
Sissors 24:fb3399713710 1665 // No Hardware Backlight pin
Sissors 24:fb3399713710 1666 _bl = NULL; //Construct dummy pin
Sissors 24:fb3399713710 1667 }
Sissors 24:fb3399713710 1668
Sissors 24:fb3399713710 1669 _init();
Sissors 24:fb3399713710 1670 }
Sissors 24:fb3399713710 1671
wim 25:6162b31128c9 1672 TextLCD_SPI_N::~TextLCD_SPI_N() {
Sissors 24:fb3399713710 1673 if (_bl != NULL) {delete _bl;} // BL pin
Sissors 24:fb3399713710 1674 }
Sissors 24:fb3399713710 1675
Sissors 24:fb3399713710 1676 // Not used in this mode
wim 25:6162b31128c9 1677 void TextLCD_SPI_N::_setEnable(bool value) {
Sissors 24:fb3399713710 1678 }
Sissors 24:fb3399713710 1679
Sissors 24:fb3399713710 1680 // Set RS pin
Sissors 24:fb3399713710 1681 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 25:6162b31128c9 1682 void TextLCD_SPI_N::_setRS(bool value) {
Sissors 24:fb3399713710 1683 _rs = value;
Sissors 24:fb3399713710 1684 }
Sissors 24:fb3399713710 1685
Sissors 24:fb3399713710 1686 // Set BL pin
wim 25:6162b31128c9 1687 void TextLCD_SPI_N::_setBL(bool value) {
wim 26:bd897a001012 1688 if (_bl) {
Sissors 24:fb3399713710 1689 _bl->write(value);
wim 26:bd897a001012 1690 }
Sissors 24:fb3399713710 1691 }
Sissors 24:fb3399713710 1692
wim 29:a3663151aa65 1693 // Not used in this mode
wim 29:a3663151aa65 1694 void TextLCD_SPI_N::_setData(int value) {
wim 29:a3663151aa65 1695 }
wim 29:a3663151aa65 1696
wim 29:a3663151aa65 1697
Sissors 24:fb3399713710 1698 // Write a byte using SPI
wim 25:6162b31128c9 1699 void TextLCD_SPI_N::_writeByte(int value) {
Sissors 24:fb3399713710 1700 _cs = 0;
Sissors 24:fb3399713710 1701 wait_us(1);
Sissors 24:fb3399713710 1702 _spi->write(value);
Sissors 24:fb3399713710 1703 wait_us(1);
Sissors 24:fb3399713710 1704 _cs = 1;
Sissors 24:fb3399713710 1705 }
Sissors 24:fb3399713710 1706
Sissors 24:fb3399713710 1707
Sissors 24:fb3399713710 1708
wim 25:6162b31128c9 1709 //-------- End TextLCD_SPI_N ------------
wim 21:9eb628d9e164 1710
wim 21:9eb628d9e164 1711
wim 21:9eb628d9e164 1712
wim 21:9eb628d9e164 1713
wim 21:9eb628d9e164 1714