C.Dupaty 03-2018 test on NUCLEO STM32-F411RE LCD 2x16, I2C interface Chinese model, adress I2C=0x4E (search on AliExpress for IIC/I2C 1602 Module) Important ! configure in TextLCD_Config.h : Valid only one of the lines : #define DFROBOT 0 // chinese OK #define YWROBOT 0 // chinese 0K #define SYDZ 1 // chinese OK Font is the same as http://www.farnell.com/datasheets/2362518.pdf

Fork of TextLCD by Wim Huiskamp

/* Hello World! for the TextLCD Enhanced Library C.Dupaty 03-2018 test on NUCLEO STM32-F411RE LCD 2x16, I2C interface Chinese model, adress I2C=0x4E (search on AliExpress for IIC/I2C 1602 Module) Important ! configure in TextLCD_Config.h : Valid only one of the lines :

  1. define DFROBOT 0 chinese OK
  2. define YWROBOT 0 chinese 0K
  3. define SYDZ 1 chinese OK Font is the same as http://www.farnell.com/datasheets/2362518.pdf
  • /
Committer:
wim
Date:
Sat May 10 21:34:51 2014 +0000
Revision:
25:6162b31128c9
Parent:
24:fb3399713710
Child:
26:bd897a001012
Added support for controllers with native SPI interface.

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