Updated for more display types. Fixed memoryaddress confusion in address() method. Added new getAddress() method. Added support for UDCs, Backlight control and other features such as control through I2C and SPI port expanders and controllers with native I2C and SPI interfaces. Refactored to fix issue with pins that are default declared as NC.

Dependents:   GPSDevice TestTextLCD SD to Flash Data Transfer DrumMachine ... more

Fork of TextLCD by Simon Ford

Example

Hello World! for the TextLCD

#include "mbed.h"
#include "TextLCD.h"
 
// Host PC Communication channels
Serial pc(USBTX, USBRX); // tx, rx
 
// I2C Communication
I2C i2c_lcd(p28,p27); // SDA, SCL
 
// SPI Communication
SPI spi_lcd(p5, NC, p7); // MOSI, MISO, SCLK

//TextLCD lcd(p15, p16, p17, p18, p19, p20);                // RS, E, D4-D7, LCDType=LCD16x2, BL=NC, E2=NC, LCDTCtrl=HD44780
//TextLCD_SPI lcd(&spi_lcd, p8, TextLCD::LCD40x4);   // SPI bus, 74595 expander, CS pin, LCD Type  
TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD20x4);  // I2C bus, PCF8574 Slaveaddress, LCD Type
//TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD16x2, TextLCD::WS0010); // I2C bus, PCF8574 Slaveaddress, LCD Type, Device Type
//TextLCD_SPI_N lcd(&spi_lcd, p8, p9);               // SPI bus, CS pin, RS pin, LCDType=LCD16x2, BL=NC, LCDTCtrl=ST7032_3V3   
//TextLCD_I2C_N lcd(&i2c_lcd, ST7032_SA, TextLCD::LCD16x2, NC, TextLCD::ST7032_3V3); // I2C bus, Slaveaddress, LCD Type, BL=NC, LCDTCtrl=ST7032_3V3  

int main() {
    pc.printf("LCD Test. Columns=%d, Rows=%d\n\r", lcd.columns(), lcd.rows());
    
    for (int row=0; row<lcd.rows(); row++) {
      int col=0;
      
      pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
//      lcd.putc('-');
      lcd.putc('0' + row);      
      
      for (col=1; col<lcd.columns()-1; col++) {    
        lcd.putc('*');
      }
 
      pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
      lcd.putc('+');
        
    }    
    
// Show cursor as blinking character
    lcd.setCursor(TextLCD::CurOff_BlkOn);
 
// Set and show user defined characters. A maximum of 8 UDCs are supported by the HD44780.
// They are defined by a 5x7 bitpattern. 
    lcd.setUDC(0, (char *) udc_0);  // Show |>
    lcd.putc(0);    
    lcd.setUDC(1, (char *) udc_1);  // Show <|
    lcd.putc(1);    

}

Handbook page

More info is here

Committer:
wim
Date:
Wed Apr 02 17:49:55 2014 +0000
Revision:
22:35742ec80c24
Parent:
21:9eb628d9e164
Child:
23:d47f226efb24
Refactored TextLCD bus version to fix issue with pins default defined as NC.; Note: I2C and SPI versions now need to be declared as TextLCD_I2C() or TextLCD_SPI() in user code.

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