In TextLCD_I2C_N Class, added void setContrast(unsigned char c) function as temporary. This is for ST7032i non-volume type contrast control.

Dependents:   LPC1114_data_logger RTC_w_COM Frequency_Counter_w_GPS_1PPS CW_Decoder_using_FFT_on_F446 ... more

Fork of TextLCD by Wim Huiskamp

In TextLCD_I2C_N Class, added void setContrast(unsigned char c) function as temporary.

Committer:
kenjiArai
Date:
Sun Jun 15 03:22:32 2014 +0000
Revision:
29:986538f94abe
Parent:
28:30fa94f7341c
Child:
30:4c57a022a56c
Added setContrast() function for ST7032i

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