Wim Huiskamp / TextLCD

Dependents:   Projeto_CCM_Maquinas_MotorPasso Projeto_CCM_Maquinas_MotorDC

Committer:
wim
Date:
Sun Jun 29 14:55:50 2014 +0000
Revision:
31:ef31cd8a00d1
Parent:
30:033048611c01
Child:
32:59c4b8f648d4
Added Support for native I2C controllers (PCF21XX, AIP31068), added LCDTypes for 3 and 4 line displays. Encoded features in LCDTypes and LCDCtrl enumerators to ease code maintenance and improve sanity checks.

Who changed what in which revision?

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