I2C...

Dependents:   Timer_TestOverflow

Fork of TextLCD by Wim Huiskamp

Committer:
wim
Date:
Sat Jun 28 14:27:32 2014 +0000
Revision:
30:033048611c01
Parent:
29:a3663151aa65
Child:
31:ef31cd8a00d1
Tested AIP31068 for I2C, tested SPI3_9 and SPI3_10

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 #if(0)
wim 8:03116f75b66e 816 // This is new method to return the memory address based on row, column and displaytype.
wim 8:03116f75b66e 817 //
wim 29:a3663151aa65 818 /** Return the memoryaddress of screen column and row location
wim 29:a3663151aa65 819 *
wim 29:a3663151aa65 820 * @param column The horizontal position from the left, indexed from 0
wim 29:a3663151aa65 821 * @param row The vertical position from the top, indexed from 0
wim 29:a3663151aa65 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 29:a3663151aa65 825 */
wim 21:9eb628d9e164 826 int TextLCD_Base::getAddress(int column, int row) {
wim 8:03116f75b66e 827
wim 8:03116f75b66e 828 switch (_type) {
wim 8:03116f75b66e 829 case LCD8x1:
wim 30:033048611c01 830 // case LCD12x1:
wim 30:033048611c01 831 // case LCD16x1B:
wim 30:033048611c01 832 // case LCD20x1:
wim 30:033048611c01 833 case LCD24x1:
wim 30:033048611c01 834 // case LCD40x1:
wim 8:03116f75b66e 835 return 0x00 + column;
wim 18:bd65dc10f27f 836
wim 29:a3663151aa65 837 case LCD16x1:
wim 29:a3663151aa65 838 // LCD16x1 is a special layout of LCD8x2
wim 29:a3663151aa65 839 if (column<8)
wim 29:a3663151aa65 840 return 0x00 + column;
wim 29:a3663151aa65 841 else
wim 29:a3663151aa65 842 return 0x40 + (column - 8);
wim 29:a3663151aa65 843
wim 30:033048611c01 844 case LCD8x2D:
wim 18:bd65dc10f27f 845 // LCD8x2B is a special layout of LCD16x1
wim 18:bd65dc10f27f 846 if (row==0)
wim 18:bd65dc10f27f 847 return 0x00 + column;
wim 18:bd65dc10f27f 848 else
wim 18:bd65dc10f27f 849 return 0x08 + column;
wim 18:bd65dc10f27f 850
wim 29:a3663151aa65 851 case LCD8x2:
wim 29:a3663151aa65 852 case LCD12x2:
wim 29:a3663151aa65 853 case LCD16x2:
wim 29:a3663151aa65 854 case LCD20x2:
wim 29:a3663151aa65 855 case LCD24x2:
wim 29:a3663151aa65 856 case LCD40x2:
wim 29:a3663151aa65 857 return 0x00 + (row * 0x40) + column;
wim 13:24506ba22480 858
wim 29:a3663151aa65 859 // Not sure about this one, seems wrong.
wim 29:a3663151aa65 860 // Left in for compatibility with original library
wim 29:a3663151aa65 861 case LCD16x2B:
wim 29:a3663151aa65 862 return 0x00 + (row * 40) + column;
wim 29:a3663151aa65 863
wim 29:a3663151aa65 864
wim 28:30fa94f7341c 865 // Special mode for ST7036
wim 28:30fa94f7341c 866 // case LCD16x3:
wim 28:30fa94f7341c 867
wim 29:a3663151aa65 868 // Special mode for PCF2116
wim 29:a3663151aa65 869 case LCD12x3B:
wim 30:033048611c01 870 //Display bottom three rows of four
wim 29:a3663151aa65 871 switch (row) {
wim 29:a3663151aa65 872 case 0:
wim 29:a3663151aa65 873 return 0x20 + column;
wim 29:a3663151aa65 874 case 1:
wim 29:a3663151aa65 875 return 0x40 + column;
wim 29:a3663151aa65 876 case 2:
wim 29:a3663151aa65 877 return 0x60 + column;
wim 29:a3663151aa65 878 }
wim 29:a3663151aa65 879
wim 30:033048611c01 880 #if(0)
wim 30:033048611c01 881 case LCD12x3C:
wim 30:033048611c01 882 //Display top three rows of four
wim 30:033048611c01 883 switch (row) {
wim 30:033048611c01 884 case 0:
wim 30:033048611c01 885 return 0x00 + column;
wim 30:033048611c01 886 case 1:
wim 30:033048611c01 887 return 0x20 + column;
wim 30:033048611c01 888 case 2:
wim 30:033048611c01 889 return 0x40 + column;
wim 30:033048611c01 890 }
wim 30:033048611c01 891 #endif
wim 30:033048611c01 892
wim 29:a3663151aa65 893 case LCD12x4:
wim 28:30fa94f7341c 894 switch (row) {
wim 28:30fa94f7341c 895 case 0:
wim 28:30fa94f7341c 896 return 0x00 + column;
wim 28:30fa94f7341c 897 case 1:
wim 29:a3663151aa65 898 return 0x40 + column;
wim 28:30fa94f7341c 899 case 2:
wim 29:a3663151aa65 900 return 0x0C + column;
wim 29:a3663151aa65 901 case 3:
wim 29:a3663151aa65 902 return 0x4C + column;
wim 28:30fa94f7341c 903 }
wim 28:30fa94f7341c 904
wim 28:30fa94f7341c 905 // Special mode for PCF2116 (and KS0078)
wim 28:30fa94f7341c 906 case LCD12x4B:
wim 28:30fa94f7341c 907 switch (row) {
wim 28:30fa94f7341c 908 case 0:
wim 28:30fa94f7341c 909 return 0x00 + column;
wim 28:30fa94f7341c 910 case 1:
wim 28:30fa94f7341c 911 return 0x20 + column;
wim 28:30fa94f7341c 912 case 2:
wim 28:30fa94f7341c 913 return 0x40 + column;
wim 28:30fa94f7341c 914 case 3:
wim 28:30fa94f7341c 915 return 0x60 + column;
wim 28:30fa94f7341c 916 }
wim 28:30fa94f7341c 917
wim 8:03116f75b66e 918 case LCD16x4:
wim 8:03116f75b66e 919 switch (row) {
wim 8:03116f75b66e 920 case 0:
wim 8:03116f75b66e 921 return 0x00 + column;
wim 8:03116f75b66e 922 case 1:
wim 8:03116f75b66e 923 return 0x40 + column;
wim 8:03116f75b66e 924 case 2:
wim 8:03116f75b66e 925 return 0x10 + column;
wim 8:03116f75b66e 926 case 3:
wim 8:03116f75b66e 927 return 0x50 + column;
wim 8:03116f75b66e 928 }
wim 8:03116f75b66e 929
wim 8:03116f75b66e 930 case LCD20x4:
wim 8:03116f75b66e 931 switch (row) {
wim 8:03116f75b66e 932 case 0:
wim 8:03116f75b66e 933 return 0x00 + column;
wim 8:03116f75b66e 934 case 1:
wim 8:03116f75b66e 935 return 0x40 + column;
wim 8:03116f75b66e 936 case 2:
wim 8:03116f75b66e 937 return 0x14 + column;
wim 8:03116f75b66e 938 case 3:
wim 8:03116f75b66e 939 return 0x54 + column;
wim 8:03116f75b66e 940 }
wim 8:03116f75b66e 941
wim 10:dd9b3a696acd 942 // Special mode for KS0078
wim 29:a3663151aa65 943 case LCD24x4B:
wim 10:dd9b3a696acd 944 switch (row) {
wim 10:dd9b3a696acd 945 case 0:
wim 10:dd9b3a696acd 946 return 0x00 + column;
wim 10:dd9b3a696acd 947 case 1:
wim 10:dd9b3a696acd 948 return 0x20 + column;
wim 10:dd9b3a696acd 949 case 2:
wim 10:dd9b3a696acd 950 return 0x40 + column;
wim 10:dd9b3a696acd 951 case 3:
wim 10:dd9b3a696acd 952 return 0x60 + column;
wim 10:dd9b3a696acd 953 }
wim 10:dd9b3a696acd 954
wim 15:b70ebfffb258 955 case LCD40x4:
wim 15:b70ebfffb258 956 // LCD40x4 is a special case since it has 2 controllers
wim 15:b70ebfffb258 957 // Each controller is configured as 40x2
wim 15:b70ebfffb258 958 if (row<2) {
wim 15:b70ebfffb258 959 // Test to see if we need to switch between controllers
wim 19:c747b9e2e7b8 960 if (_ctrl_idx != _LCDCtrl_0) {
wim 17:652ab113bc2e 961
wim 15:b70ebfffb258 962 // Second LCD controller Cursor Off
wim 21:9eb628d9e164 963 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 15:b70ebfffb258 964
wim 15:b70ebfffb258 965 // Select primary controller
wim 19:c747b9e2e7b8 966 _ctrl_idx = _LCDCtrl_0;
wim 15:b70ebfffb258 967
wim 15:b70ebfffb258 968 // Restore cursormode on primary LCD controller
wim 17:652ab113bc2e 969 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 15:b70ebfffb258 970 }
wim 15:b70ebfffb258 971
wim 15:b70ebfffb258 972 return 0x00 + (row * 0x40) + column;
wim 15:b70ebfffb258 973 }
wim 15:b70ebfffb258 974 else {
wim 15:b70ebfffb258 975
wim 15:b70ebfffb258 976 // Test to see if we need to switch between controllers
wim 19:c747b9e2e7b8 977 if (_ctrl_idx != _LCDCtrl_1) {
wim 15:b70ebfffb258 978 // Primary LCD controller Cursor Off
wim 21:9eb628d9e164 979 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 15:b70ebfffb258 980
wim 15:b70ebfffb258 981 // Select secondary controller
wim 19:c747b9e2e7b8 982 _ctrl_idx = _LCDCtrl_1;
wim 15:b70ebfffb258 983
wim 15:b70ebfffb258 984 // Restore cursormode on secondary LCD controller
wim 17:652ab113bc2e 985 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 15:b70ebfffb258 986 }
wim 15:b70ebfffb258 987
wim 15:b70ebfffb258 988 return 0x00 + ((row-2) * 0x40) + column;
wim 15:b70ebfffb258 989 }
wim 8:03116f75b66e 990
wim 8:03116f75b66e 991 // Should never get here.
wim 8:03116f75b66e 992 default:
wim 8:03116f75b66e 993 return 0x00;
wim 8:03116f75b66e 994 }
wim 8:03116f75b66e 995 }
wim 8:03116f75b66e 996
wim 30:033048611c01 997 #else
wim 30:033048611c01 998
wim 30:033048611c01 999 //Test of Addressing Mode encoded in LCDType
wim 30:033048611c01 1000
wim 30:033048611c01 1001 // This is new method to return the memory address based on row, column and displaytype.
wim 30:033048611c01 1002 //
wim 30:033048611c01 1003 /** Return the memoryaddress of screen column and row location
wim 30:033048611c01 1004 *
wim 30:033048611c01 1005 * @param column The horizontal position from the left, indexed from 0
wim 30:033048611c01 1006 * @param row The vertical position from the top, indexed from 0
wim 30:033048611c01 1007 * @param return The memoryaddress of screen column and row location
wim 30:033048611c01 1008 *
wim 30:033048611c01 1009 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware
wim 30:033048611c01 1010 */
wim 30:033048611c01 1011 int TextLCD_Base::getAddress(int column, int row) {
wim 30:033048611c01 1012
wim 30:033048611c01 1013 switch (_addr_mode) {
wim 30:033048611c01 1014
wim 30:033048611c01 1015 case LCD_T_A:
wim 30:033048611c01 1016 //Default addressing mode for 1, 2 and 4 rows (except 40x4)
wim 30:033048611c01 1017 //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 1018 //Displays top rows when less than four are used.
wim 30:033048611c01 1019 switch (row) {
wim 30:033048611c01 1020 case 0:
wim 30:033048611c01 1021 return 0x00 + column;
wim 30:033048611c01 1022 case 1:
wim 30:033048611c01 1023 return 0x40 + column;
wim 30:033048611c01 1024 case 2:
wim 30:033048611c01 1025 return 0x00 + _nr_cols + column;
wim 30:033048611c01 1026 case 3:
wim 30:033048611c01 1027 return 0x40 + _nr_cols + column;
wim 30:033048611c01 1028 // Should never get here.
wim 30:033048611c01 1029 default:
wim 30:033048611c01 1030 return 0x00;
wim 30:033048611c01 1031 }
wim 30:033048611c01 1032
wim 30:033048611c01 1033 case LCD_T_B:
wim 30:033048611c01 1034 // LCD8x2B is a special layout of LCD16x1
wim 30:033048611c01 1035 if (row==0)
wim 30:033048611c01 1036 return 0x00 + column;
wim 30:033048611c01 1037 else
wim 30:033048611c01 1038 // return _nr_cols + column;
wim 30:033048611c01 1039 return 0x08 + column;
wim 30:033048611c01 1040
wim 30:033048611c01 1041 case LCD_T_C:
wim 30:033048611c01 1042 // LCD16x1C is a special layout of LCD8x2
wim 30:033048611c01 1043 if (column<8)
wim 30:033048611c01 1044 return 0x00 + column;
wim 30:033048611c01 1045 else
wim 30:033048611c01 1046 return 0x40 + (column - 8);
wim 30:033048611c01 1047
wim 30:033048611c01 1048 // Not sure about this one, seems wrong.
wim 30:033048611c01 1049 // Left in for compatibility with original library
wim 30:033048611c01 1050 // case LCD16x2B:
wim 30:033048611c01 1051 // return 0x00 + (row * 40) + column;
wim 30:033048611c01 1052
wim 30:033048611c01 1053
wim 30:033048611c01 1054 case LCD_T_D:
wim 30:033048611c01 1055 //Alternate addressing mode for 3 and 4 row displays (except 40x4). Used by PCF21XX, KS0078
wim 30:033048611c01 1056 //The 4 available rows start at a hardcoded address.
wim 30:033048611c01 1057 //Displays top rows when less than four are used.
wim 30:033048611c01 1058 switch (row) {
wim 30:033048611c01 1059 case 0:
wim 30:033048611c01 1060 return 0x00 + column;
wim 30:033048611c01 1061 case 1:
wim 30:033048611c01 1062 return 0x20 + column;
wim 30:033048611c01 1063 case 2:
wim 30:033048611c01 1064 return 0x40 + column;
wim 30:033048611c01 1065 case 3:
wim 30:033048611c01 1066 return 0x60 + column;
wim 30:033048611c01 1067 // Should never get here.
wim 30:033048611c01 1068 default:
wim 30:033048611c01 1069 return 0x00;
wim 30:033048611c01 1070 }
wim 30:033048611c01 1071
wim 30:033048611c01 1072 case LCD_T_D1:
wim 30:033048611c01 1073 //Alternate addressing mode for 3 row displays. Used by PCF21XX, KS0078
wim 30:033048611c01 1074 //The 4 available rows start at a hardcoded address.
wim 30:033048611c01 1075 //Skips top row of 4 row display and starts display at row 1
wim 30:033048611c01 1076 switch (row) {
wim 30:033048611c01 1077 case 0:
wim 30:033048611c01 1078 return 0x20 + column;
wim 30:033048611c01 1079 case 1:
wim 30:033048611c01 1080 return 0x40 + column;
wim 30:033048611c01 1081 case 2:
wim 30:033048611c01 1082 return 0x60 + column;
wim 30:033048611c01 1083 // Should never get here.
wim 30:033048611c01 1084 default:
wim 30:033048611c01 1085 return 0x00;
wim 30:033048611c01 1086 }
wim 30:033048611c01 1087
wim 30:033048611c01 1088 case LCD_T_E:
wim 30:033048611c01 1089 // LCD40x4 is a special case since it has 2 controllers.
wim 30:033048611c01 1090 // Each controller is configured as 40x2 (Type A)
wim 30:033048611c01 1091 if (row<2) {
wim 30:033048611c01 1092 // Test to see if we need to switch between controllers
wim 30:033048611c01 1093 if (_ctrl_idx != _LCDCtrl_0) {
wim 30:033048611c01 1094
wim 30:033048611c01 1095 // Second LCD controller Cursor Off
wim 30:033048611c01 1096 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 30:033048611c01 1097
wim 30:033048611c01 1098 // Select primary controller
wim 30:033048611c01 1099 _ctrl_idx = _LCDCtrl_0;
wim 30:033048611c01 1100
wim 30:033048611c01 1101 // Restore cursormode on primary LCD controller
wim 30:033048611c01 1102 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 1103 }
wim 30:033048611c01 1104
wim 30:033048611c01 1105 return 0x00 + (row * 0x40) + column;
wim 30:033048611c01 1106 }
wim 30:033048611c01 1107 else {
wim 30:033048611c01 1108
wim 30:033048611c01 1109 // Test to see if we need to switch between controllers
wim 30:033048611c01 1110 if (_ctrl_idx != _LCDCtrl_1) {
wim 30:033048611c01 1111 // Primary LCD controller Cursor Off
wim 30:033048611c01 1112 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 30:033048611c01 1113
wim 30:033048611c01 1114 // Select secondary controller
wim 30:033048611c01 1115 _ctrl_idx = _LCDCtrl_1;
wim 30:033048611c01 1116
wim 30:033048611c01 1117 // Restore cursormode on secondary LCD controller
wim 30:033048611c01 1118 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 1119 }
wim 30:033048611c01 1120
wim 30:033048611c01 1121 return 0x00 + ((row-2) * 0x40) + column;
wim 30:033048611c01 1122 }
wim 30:033048611c01 1123
wim 30:033048611c01 1124 // Should never get here.
wim 30:033048611c01 1125 default:
wim 30:033048611c01 1126 return 0x00;
wim 30:033048611c01 1127 }
wim 30:033048611c01 1128 }
wim 30:033048611c01 1129
wim 30:033048611c01 1130
wim 30:033048611c01 1131 #endif
wim 30:033048611c01 1132
wim 30:033048611c01 1133
wim 8:03116f75b66e 1134
wim 29:a3663151aa65 1135 /** Set the memoryaddress of screen column and row location
wim 29:a3663151aa65 1136 *
wim 29:a3663151aa65 1137 * @param column The horizontal position from the left, indexed from 0
wim 29:a3663151aa65 1138 * @param row The vertical position from the top, indexed from 0
wim 29:a3663151aa65 1139 */
wim 21:9eb628d9e164 1140 void TextLCD_Base::setAddress(int column, int row) {
wim 15:b70ebfffb258 1141
wim 15:b70ebfffb258 1142 // Sanity Check column
wim 15:b70ebfffb258 1143 if (column < 0) {
wim 15:b70ebfffb258 1144 _column = 0;
wim 15:b70ebfffb258 1145 }
wim 15:b70ebfffb258 1146 else if (column >= columns()) {
wim 15:b70ebfffb258 1147 _column = columns() - 1;
wim 15:b70ebfffb258 1148 } else _column = column;
wim 8:03116f75b66e 1149
wim 15:b70ebfffb258 1150 // Sanity Check row
wim 15:b70ebfffb258 1151 if (row < 0) {
wim 15:b70ebfffb258 1152 _row = 0;
wim 15:b70ebfffb258 1153 }
wim 15:b70ebfffb258 1154 else if (row >= rows()) {
wim 15:b70ebfffb258 1155 _row = rows() - 1;
wim 15:b70ebfffb258 1156 } else _row = row;
wim 15:b70ebfffb258 1157
wim 15:b70ebfffb258 1158
wim 15:b70ebfffb258 1159 // Compute the memory address
wim 15:b70ebfffb258 1160 // For LCD40x4: switch controllers if needed
wim 15:b70ebfffb258 1161 // switch cursor if needed
wim 15:b70ebfffb258 1162 int addr = getAddress(_column, _row);
wim 8:03116f75b66e 1163
wim 13:24506ba22480 1164 _writeCommand(0x80 | addr);
wim 8:03116f75b66e 1165 }
simon 1:ac48b187213c 1166
wim 29:a3663151aa65 1167
wim 29:a3663151aa65 1168 /** Return the number of columns
wim 29:a3663151aa65 1169 *
wim 29:a3663151aa65 1170 * @param return The number of columns
wim 30:033048611c01 1171 *
wim 30:033048611c01 1172 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware
wim 29:a3663151aa65 1173 */
wim 21:9eb628d9e164 1174 int TextLCD_Base::columns() {
wim 30:033048611c01 1175
wim 30:033048611c01 1176 // Columns encoded in b7..b0
wim 30:033048611c01 1177 //return (_type & 0xFF);
wim 30:033048611c01 1178 return _nr_cols;
wim 30:033048611c01 1179
wim 30:033048611c01 1180 #if(0)
simon 1:ac48b187213c 1181 switch (_type) {
wim 8:03116f75b66e 1182 case LCD8x1:
wim 8:03116f75b66e 1183 case LCD8x2:
wim 18:bd65dc10f27f 1184 case LCD8x2B:
wim 8:03116f75b66e 1185 return 8;
wim 15:b70ebfffb258 1186
wim 15:b70ebfffb258 1187 case LCD12x2:
wim 29:a3663151aa65 1188 case LCD12x3B:
wim 30:033048611c01 1189 // case LCD12x3C:
wim 15:b70ebfffb258 1190 case LCD12x4:
wim 29:a3663151aa65 1191 case LCD12x4B:
wim 15:b70ebfffb258 1192 return 12;
wim 8:03116f75b66e 1193
wim 13:24506ba22480 1194 case LCD16x1:
simon 1:ac48b187213c 1195 case LCD16x2:
simon 1:ac48b187213c 1196 case LCD16x2B:
wim 28:30fa94f7341c 1197 // case LCD16x3:
wim 8:03116f75b66e 1198 case LCD16x4:
wim 8:03116f75b66e 1199 return 16;
wim 8:03116f75b66e 1200
wim 30:033048611c01 1201 // case LCD20x1:
wim 8:03116f75b66e 1202 case LCD20x2:
wim 8:03116f75b66e 1203 case LCD20x4:
wim 8:03116f75b66e 1204 return 20;
wim 8:03116f75b66e 1205
wim 29:a3663151aa65 1206 case LCD24x1:
wim 8:03116f75b66e 1207 case LCD24x2:
wim 30:033048611c01 1208 // case LCD24x3B:
wim 29:a3663151aa65 1209 case LCD24x4B:
wim 8:03116f75b66e 1210 return 24;
wim 9:0893d986e717 1211
wim 30:033048611c01 1212 // case LCD40x1:
wim 9:0893d986e717 1213 case LCD40x2:
wim 15:b70ebfffb258 1214 case LCD40x4:
wim 9:0893d986e717 1215 return 40;
wim 8:03116f75b66e 1216
wim 8:03116f75b66e 1217 // Should never get here.
simon 1:ac48b187213c 1218 default:
wim 8:03116f75b66e 1219 return 0;
simon 1:ac48b187213c 1220 }
wim 30:033048611c01 1221 #endif
simon 1:ac48b187213c 1222 }
simon 1:ac48b187213c 1223
wim 29:a3663151aa65 1224 /** Return the number of rows
wim 29:a3663151aa65 1225 *
wim 29:a3663151aa65 1226 * @param return The number of rows
wim 30:033048611c01 1227 *
wim 30:033048611c01 1228 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware
wim 29:a3663151aa65 1229 */
wim 21:9eb628d9e164 1230 int TextLCD_Base::rows() {
wim 30:033048611c01 1231
wim 30:033048611c01 1232 // Rows encoded in b15..b8
wim 30:033048611c01 1233 //return ((_type >> 8) & 0xFF);
wim 30:033048611c01 1234 return _nr_rows;
wim 30:033048611c01 1235
wim 30:033048611c01 1236 #if(0)
simon 1:ac48b187213c 1237 switch (_type) {
wim 8:03116f75b66e 1238 case LCD8x1:
wim 13:24506ba22480 1239 case LCD16x1:
wim 30:033048611c01 1240 // case LCD20x1:
wim 29:a3663151aa65 1241 case LCD24x1:
wim 30:033048611c01 1242 // case LCD40x1:
wim 8:03116f75b66e 1243 return 1;
wim 8:03116f75b66e 1244
wim 15:b70ebfffb258 1245 case LCD8x2:
wim 18:bd65dc10f27f 1246 case LCD8x2B:
wim 15:b70ebfffb258 1247 case LCD12x2:
simon 1:ac48b187213c 1248 case LCD16x2:
simon 1:ac48b187213c 1249 case LCD16x2B:
simon 1:ac48b187213c 1250 case LCD20x2:
wim 8:03116f75b66e 1251 case LCD24x2:
wim 9:0893d986e717 1252 case LCD40x2:
wim 8:03116f75b66e 1253 return 2;
wim 28:30fa94f7341c 1254
wim 29:a3663151aa65 1255 case LCD12x3B:
wim 30:033048611c01 1256 // case LCD12x3C:
wim 28:30fa94f7341c 1257 // case LCD16x3:
wim 30:033048611c01 1258 // case LCD24x3B:
wim 29:a3663151aa65 1259 return 3;
wim 8:03116f75b66e 1260
wim 15:b70ebfffb258 1261 case LCD12x4:
wim 29:a3663151aa65 1262 case LCD12x4B:
wim 8:03116f75b66e 1263 case LCD16x4:
wim 8:03116f75b66e 1264 case LCD20x4:
wim 29:a3663151aa65 1265 case LCD24x4B:
wim 15:b70ebfffb258 1266 case LCD40x4:
wim 8:03116f75b66e 1267 return 4;
wim 12:6bf9d9957d31 1268
wim 12:6bf9d9957d31 1269 // Should never get here.
simon 1:ac48b187213c 1270 default:
wim 8:03116f75b66e 1271 return 0;
simon 1:ac48b187213c 1272 }
wim 30:033048611c01 1273 #endif
simon 1:ac48b187213c 1274 }
wim 10:dd9b3a696acd 1275
wim 29:a3663151aa65 1276 /** Set the Cursormode
wim 29:a3663151aa65 1277 *
wim 29:a3663151aa65 1278 * @param cursorMode The Cursor mode (CurOff_BlkOff, CurOn_BlkOff, CurOff_BlkOn, CurOn_BlkOn)
wim 29:a3663151aa65 1279 */
wim 21:9eb628d9e164 1280 void TextLCD_Base::setCursor(LCDCursor cursorMode) {
wim 15:b70ebfffb258 1281
wim 17:652ab113bc2e 1282 // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on
wim 17:652ab113bc2e 1283 _currentCursor = cursorMode;
wim 10:dd9b3a696acd 1284
wim 17:652ab113bc2e 1285 // Configure only current LCD controller
wim 17:652ab113bc2e 1286 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 15:b70ebfffb258 1287
wim 15:b70ebfffb258 1288 }
wim 15:b70ebfffb258 1289
wim 29:a3663151aa65 1290 /** Set the Displaymode
wim 29:a3663151aa65 1291 *
wim 29:a3663151aa65 1292 * @param displayMode The Display mode (DispOff, DispOn)
wim 29:a3663151aa65 1293 */
wim 21:9eb628d9e164 1294 void TextLCD_Base::setMode(LCDMode displayMode) {
wim 17:652ab113bc2e 1295
wim 17:652ab113bc2e 1296 // Save new displayMode, needed when 2 controllers are in use or when cursor is changed
wim 17:652ab113bc2e 1297 _currentMode = displayMode;
wim 15:b70ebfffb258 1298
wim 17:652ab113bc2e 1299 // Select and configure second LCD controller when needed
wim 17:652ab113bc2e 1300 if(_type==LCD40x4) {
wim 21:9eb628d9e164 1301 if (_ctrl_idx==_LCDCtrl_0) {
wim 17:652ab113bc2e 1302 // Configure primary LCD controller
wim 17:652ab113bc2e 1303 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 11:9ec02df863a1 1304
wim 17:652ab113bc2e 1305 // Select 2nd controller
wim 21:9eb628d9e164 1306 _ctrl_idx=_LCDCtrl_1;
wim 17:652ab113bc2e 1307
wim 17:652ab113bc2e 1308 // Configure secondary LCD controller
wim 21:9eb628d9e164 1309 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 11:9ec02df863a1 1310
wim 17:652ab113bc2e 1311 // Restore current controller
wim 21:9eb628d9e164 1312 _ctrl_idx=_LCDCtrl_0;
wim 17:652ab113bc2e 1313 }
wim 17:652ab113bc2e 1314 else {
wim 17:652ab113bc2e 1315 // Select primary controller
wim 21:9eb628d9e164 1316 _ctrl_idx=_LCDCtrl_0;
wim 17:652ab113bc2e 1317
wim 17:652ab113bc2e 1318 // Configure primary LCD controller
wim 21:9eb628d9e164 1319 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 17:652ab113bc2e 1320
wim 17:652ab113bc2e 1321 // Restore current controller
wim 21:9eb628d9e164 1322 _ctrl_idx=_LCDCtrl_1;
wim 11:9ec02df863a1 1323
wim 17:652ab113bc2e 1324 // Configure secondary LCD controller
wim 17:652ab113bc2e 1325 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 10:dd9b3a696acd 1326 }
wim 17:652ab113bc2e 1327 }
wim 17:652ab113bc2e 1328 else {
wim 17:652ab113bc2e 1329 // Configure primary LCD controller
wim 17:652ab113bc2e 1330 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 1331 }
wim 17:652ab113bc2e 1332 }
wim 17:652ab113bc2e 1333
wim 17:652ab113bc2e 1334
wim 29:a3663151aa65 1335 /** Low level method to restore the cursortype and display mode for current controller
wim 29:a3663151aa65 1336 */
wim 21:9eb628d9e164 1337 void TextLCD_Base::_setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType) {
wim 17:652ab113bc2e 1338
wim 17:652ab113bc2e 1339 // Configure current LCD controller
wim 17:652ab113bc2e 1340 _writeCommand(0x08 | displayMode | cursorType);
wim 10:dd9b3a696acd 1341 }
wim 10:dd9b3a696acd 1342
wim 29:a3663151aa65 1343 /** Set the Backlight mode
wim 29:a3663151aa65 1344 *
wim 29:a3663151aa65 1345 * @param backlightMode The Backlight mode (LightOff, LightOn)
wim 29:a3663151aa65 1346 */
wim 21:9eb628d9e164 1347 void TextLCD_Base::setBacklight(LCDBacklight backlightMode) {
wim 20:e0da005a777f 1348
wim 20:e0da005a777f 1349 if (backlightMode == LightOn) {
wim 21:9eb628d9e164 1350 this->_setBL(true);
wim 20:e0da005a777f 1351 }
wim 20:e0da005a777f 1352 else {
wim 21:9eb628d9e164 1353 this->_setBL(false);
wim 20:e0da005a777f 1354 }
wim 20:e0da005a777f 1355 }
wim 20:e0da005a777f 1356
wim 29:a3663151aa65 1357 /** Set User Defined Characters
wim 29:a3663151aa65 1358 *
wim 29:a3663151aa65 1359 * @param unsigned char c The Index of the UDC (0..7)
wim 29:a3663151aa65 1360 * @param char *udc_data The bitpatterns for the UDC (8 bytes of 5 significant bits)
wim 29:a3663151aa65 1361 */
wim 21:9eb628d9e164 1362 void TextLCD_Base::setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 1363
wim 15:b70ebfffb258 1364 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 1365 if(_type==LCD40x4) {
wim 19:c747b9e2e7b8 1366 _LCDCtrl_Idx current_ctrl_idx = _ctrl_idx; // Temp save current controller
wim 15:b70ebfffb258 1367
wim 15:b70ebfffb258 1368 // Select primary controller
wim 21:9eb628d9e164 1369 _ctrl_idx=_LCDCtrl_0;
wim 15:b70ebfffb258 1370
wim 15:b70ebfffb258 1371 // Configure primary LCD controller
wim 15:b70ebfffb258 1372 _setUDC(c, udc_data);
wim 15:b70ebfffb258 1373
wim 15:b70ebfffb258 1374 // Select 2nd controller
wim 21:9eb628d9e164 1375 _ctrl_idx=_LCDCtrl_1;
wim 15:b70ebfffb258 1376
wim 15:b70ebfffb258 1377 // Configure secondary LCD controller
wim 15:b70ebfffb258 1378 _setUDC(c, udc_data);
wim 11:9ec02df863a1 1379
wim 15:b70ebfffb258 1380 // Restore current controller
wim 19:c747b9e2e7b8 1381 _ctrl_idx=current_ctrl_idx;
wim 15:b70ebfffb258 1382 }
wim 15:b70ebfffb258 1383 else {
wim 15:b70ebfffb258 1384 // Configure primary LCD controller
wim 15:b70ebfffb258 1385 _setUDC(c, udc_data);
wim 15:b70ebfffb258 1386 }
wim 15:b70ebfffb258 1387
wim 15:b70ebfffb258 1388 }
wim 15:b70ebfffb258 1389
wim 29:a3663151aa65 1390 /** Low level method to store user defined characters for current controller
wim 29:a3663151aa65 1391 */
wim 21:9eb628d9e164 1392 void TextLCD_Base::_setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 1393
wim 15:b70ebfffb258 1394 // Select CG RAM for current LCD controller
wim 15:b70ebfffb258 1395 _writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address,
wim 15:b70ebfffb258 1396 //8 sequential locations needed per UDC
wim 15:b70ebfffb258 1397 // Store UDC pattern
wim 11:9ec02df863a1 1398 for (int i=0; i<8; i++) {
wim 13:24506ba22480 1399 _writeData(*udc_data++);
wim 11:9ec02df863a1 1400 }
wim 15:b70ebfffb258 1401
wim 15:b70ebfffb258 1402 //Select DD RAM again for current LCD controller
wim 15:b70ebfffb258 1403 int addr = getAddress(_column, _row);
wim 30:033048611c01 1404 _writeCommand(0x80 | addr);
wim 11:9ec02df863a1 1405 }
wim 21:9eb628d9e164 1406
wim 23:d47f226efb24 1407 //--------- End TextLCD_Base -----------
wim 21:9eb628d9e164 1408
wim 22:35742ec80c24 1409
wim 23:d47f226efb24 1410 //--------- Start TextLCD Bus -----------
wim 21:9eb628d9e164 1411
wim 21:9eb628d9e164 1412 /* Create a TextLCD interface for using regular mbed pins
wim 21:9eb628d9e164 1413 *
wim 21:9eb628d9e164 1414 * @param rs Instruction/data control line
wim 21:9eb628d9e164 1415 * @param e Enable line (clock)
wim 21:9eb628d9e164 1416 * @param d4-d7 Data lines for using as a 4-bit interface
wim 21:9eb628d9e164 1417 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 21:9eb628d9e164 1418 * @param bl Backlight control line (optional, default = NC)
wim 21:9eb628d9e164 1419 * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
wim 21:9eb628d9e164 1420 * @param ctrl LCD controller (default = HD44780)
wim 21:9eb628d9e164 1421 */
wim 21:9eb628d9e164 1422 TextLCD::TextLCD(PinName rs, PinName e,
wim 21:9eb628d9e164 1423 PinName d4, PinName d5, PinName d6, PinName d7,
wim 21:9eb628d9e164 1424 LCDType type, PinName bl, PinName e2, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1425 TextLCD_Base(type, ctrl),
wim 22:35742ec80c24 1426 _rs(rs), _e(e), _d(d4, d5, d6, d7) {
wim 22:35742ec80c24 1427
wim 22:35742ec80c24 1428 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 22:35742ec80c24 1429 if (bl != NC) {
wim 22:35742ec80c24 1430 _bl = new DigitalOut(bl); //Construct new pin
wim 22:35742ec80c24 1431 _bl->write(0); //Deactivate
wim 22:35742ec80c24 1432 }
wim 22:35742ec80c24 1433 else {
wim 22:35742ec80c24 1434 // No Hardware Backlight pin
wim 22:35742ec80c24 1435 _bl = NULL; //Construct dummy pin
wim 22:35742ec80c24 1436 }
wim 22:35742ec80c24 1437
wim 22:35742ec80c24 1438 // 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 1439 if (e2 != NC) {
wim 22:35742ec80c24 1440 _e2 = new DigitalOut(e2); //Construct new pin
wim 22:35742ec80c24 1441 _e2->write(0); //Deactivate
wim 22:35742ec80c24 1442 }
wim 22:35742ec80c24 1443 else {
wim 22:35742ec80c24 1444 // No Hardware Enable pin
wim 22:35742ec80c24 1445 _e2 = NULL; //Construct dummy pin
wim 22:35742ec80c24 1446 }
wim 21:9eb628d9e164 1447
wim 21:9eb628d9e164 1448 _init();
wim 21:9eb628d9e164 1449 }
wim 21:9eb628d9e164 1450
wim 29:a3663151aa65 1451 /** Destruct a TextLCD interface for using regular mbed pins
wim 29:a3663151aa65 1452 *
wim 29:a3663151aa65 1453 * @param none
wim 29:a3663151aa65 1454 * @return none
wim 29:a3663151aa65 1455 */
wim 29:a3663151aa65 1456 TextLCD::~TextLCD() {
wim 29:a3663151aa65 1457 if (_bl != NULL) {delete _bl;} // BL pin
wim 29:a3663151aa65 1458 if (_e2 != NULL) {delete _e2;} // E2 pin
wim 29:a3663151aa65 1459 }
wim 29:a3663151aa65 1460
wim 29:a3663151aa65 1461
wim 22:35742ec80c24 1462 /** Set E pin (or E2 pin)
wim 22:35742ec80c24 1463 * Used for mbed pins, I2C bus expander or SPI shiftregister
wim 22:35742ec80c24 1464 * Default PinName value for E2 is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
wim 22:35742ec80c24 1465 * @param value true or false
wim 22:35742ec80c24 1466 * @return none
wim 22:35742ec80c24 1467 */
wim 21:9eb628d9e164 1468 void TextLCD::_setEnable(bool value) {
wim 21:9eb628d9e164 1469
wim 22:35742ec80c24 1470 if(_ctrl_idx==_LCDCtrl_0) {
wim 22:35742ec80c24 1471 if (value) {
wim 22:35742ec80c24 1472 _e = 1; // Set E bit
wim 22:35742ec80c24 1473 }
wim 22:35742ec80c24 1474 else {
wim 22:35742ec80c24 1475 _e = 0; // Reset E bit
wim 22:35742ec80c24 1476 }
wim 22:35742ec80c24 1477 }
wim 22:35742ec80c24 1478 else {
wim 22:35742ec80c24 1479 if (value) {
wim 22:35742ec80c24 1480 if (_e2 != NULL) {_e2->write(1);} //Set E2 bit
wim 22:35742ec80c24 1481 }
wim 22:35742ec80c24 1482 else {
wim 22:35742ec80c24 1483 if (_e2 != NULL) {_e2->write(0);} //Reset E2 bit
wim 22:35742ec80c24 1484 }
wim 22:35742ec80c24 1485 }
wim 21:9eb628d9e164 1486 }
wim 21:9eb628d9e164 1487
wim 21:9eb628d9e164 1488 // Set RS pin
wim 21:9eb628d9e164 1489 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1490 void TextLCD::_setRS(bool value) {
wim 21:9eb628d9e164 1491
wim 22:35742ec80c24 1492 if (value) {
wim 21:9eb628d9e164 1493 _rs = 1; // Set RS bit
wim 22:35742ec80c24 1494 }
wim 22:35742ec80c24 1495 else {
wim 21:9eb628d9e164 1496 _rs = 0; // Reset RS bit
wim 22:35742ec80c24 1497 }
wim 21:9eb628d9e164 1498 }
wim 21:9eb628d9e164 1499
wim 22:35742ec80c24 1500 /** Set BL pin
wim 22:35742ec80c24 1501 * Used for mbed pins, I2C bus expander or SPI shiftregister
wim 22:35742ec80c24 1502 * Default PinName value is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
wim 22:35742ec80c24 1503 * @param value true or false
wim 22:35742ec80c24 1504 * @return none
wim 22:35742ec80c24 1505 */
wim 21:9eb628d9e164 1506 void TextLCD::_setBL(bool value) {
wim 21:9eb628d9e164 1507
wim 22:35742ec80c24 1508 if (value) {
wim 22:35742ec80c24 1509 if (_bl != NULL) {_bl->write(1);} //Set BL bit
wim 22:35742ec80c24 1510 }
wim 22:35742ec80c24 1511 else {
wim 22:35742ec80c24 1512 if (_bl != NULL) {_bl->write(0);} //Reset BL bit
wim 22:35742ec80c24 1513 }
wim 21:9eb628d9e164 1514
wim 21:9eb628d9e164 1515 }
wim 21:9eb628d9e164 1516
wim 21:9eb628d9e164 1517 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1518 // Used for mbed pins, I2C bus expander or SPI shifregister
wim 21:9eb628d9e164 1519 void TextLCD::_setData(int value) {
wim 21:9eb628d9e164 1520 _d = value & 0x0F; // Write Databits
wim 21:9eb628d9e164 1521 }
wim 22:35742ec80c24 1522
wim 23:d47f226efb24 1523 //----------- End TextLCD ---------------
wim 21:9eb628d9e164 1524
wim 21:9eb628d9e164 1525
wim 23:d47f226efb24 1526 //--------- Start TextLCD_I2C -----------
wim 22:35742ec80c24 1527
wim 26:bd897a001012 1528 /** Create a TextLCD interface using an I2C PC8574 (or PCF8574A) or MCP23008 portexpander
wim 22:35742ec80c24 1529 *
wim 22:35742ec80c24 1530 * @param i2c I2C Bus
wim 26:bd897a001012 1531 * @param deviceAddress I2C slave address (PCF8574, PCF8574A or MCP23008, default = 0x40)
wim 22:35742ec80c24 1532 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 22:35742ec80c24 1533 * @param ctrl LCD controller (default = HD44780)
wim 22:35742ec80c24 1534 */
wim 21:9eb628d9e164 1535 TextLCD_I2C::TextLCD_I2C(I2C *i2c, char deviceAddress, LCDType type, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1536 TextLCD_Base(type, ctrl),
wim 21:9eb628d9e164 1537 _i2c(i2c){
wim 21:9eb628d9e164 1538
wim 22:35742ec80c24 1539 _slaveAddress = deviceAddress & 0xFE;
wim 28:30fa94f7341c 1540
wim 28:30fa94f7341c 1541 // Setup the I2C bus
wim 28:30fa94f7341c 1542 // The max bitrate for PCF8574 is 100kbit, the max bitrate for MCP23008 is 400kbit,
wim 28:30fa94f7341c 1543 // _i2c->frequency(100000);
wim 21:9eb628d9e164 1544
wim 26:bd897a001012 1545 #if (MCP23008==1)
wim 26:bd897a001012 1546 // MCP23008 portexpander Init
wim 27:22d5086f6ba6 1547 _write_register(IODIR, 0x00); // All outputs
wim 27:22d5086f6ba6 1548 _write_register(IPOL, 0x00); // No reverse polarity
wim 27:22d5086f6ba6 1549 _write_register(GPINTEN, 0x00); // No interrupt
wim 27:22d5086f6ba6 1550 _write_register(DEFVAL, 0x00); // Default value to compare against for interrupts
wim 27:22d5086f6ba6 1551 _write_register(INTCON, 0x00); // No interrupt on changes
wim 27:22d5086f6ba6 1552 _write_register(IOCON, 0x00); // Interrupt polarity
wim 27:22d5086f6ba6 1553 _write_register(GPPU, 0x00); // No Pullup
wim 27:22d5086f6ba6 1554 _write_register(INTF, 0x00); //
wim 27:22d5086f6ba6 1555 _write_register(INTCAP, 0x00); //
wim 27:22d5086f6ba6 1556 _write_register(GPIO, 0x00); // Output/Input pins
wim 27:22d5086f6ba6 1557 _write_register(OLAT, 0x00); // Output Latch
wim 26:bd897a001012 1558
wim 21:9eb628d9e164 1559 // Init the portexpander bus
wim 21:9eb628d9e164 1560 _lcd_bus = D_LCD_BUS_DEF;
wim 21:9eb628d9e164 1561
wim 21:9eb628d9e164 1562 // write the new data to the portexpander
wim 26:bd897a001012 1563 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1564 #else
wim 26:bd897a001012 1565 // PCF8574 of PCF8574A portexpander
wim 26:bd897a001012 1566
wim 26:bd897a001012 1567 // Init the portexpander bus
wim 26:bd897a001012 1568 _lcd_bus = D_LCD_BUS_DEF;
wim 26:bd897a001012 1569
wim 26:bd897a001012 1570 // write the new data to the portexpander
wim 21:9eb628d9e164 1571 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1572 #endif
wim 21:9eb628d9e164 1573
wim 30:033048611c01 1574 _init();
wim 21:9eb628d9e164 1575 }
wim 21:9eb628d9e164 1576
wim 21:9eb628d9e164 1577 // Set E pin (or E2 pin)
wim 21:9eb628d9e164 1578 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1579 void TextLCD_I2C::_setEnable(bool value) {
wim 21:9eb628d9e164 1580
wim 22:35742ec80c24 1581 if(_ctrl_idx==_LCDCtrl_0) {
wim 26:bd897a001012 1582 if (value) {
wim 22:35742ec80c24 1583 _lcd_bus |= D_LCD_E; // Set E bit
wim 26:bd897a001012 1584 }
wim 26:bd897a001012 1585 else {
wim 22:35742ec80c24 1586 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 26:bd897a001012 1587 }
wim 22:35742ec80c24 1588 }
wim 22:35742ec80c24 1589 else {
wim 26:bd897a001012 1590 if (value) {
wim 22:35742ec80c24 1591 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 26:bd897a001012 1592 }
wim 26:bd897a001012 1593 else {
wim 22:35742ec80c24 1594 _lcd_bus &= ~D_LCD_E2; // Reset E2bit
wim 26:bd897a001012 1595 }
wim 26:bd897a001012 1596 }
wim 26:bd897a001012 1597
wim 26:bd897a001012 1598 #if (MCP23008==1)
wim 26:bd897a001012 1599 // MCP23008 portexpander
wim 26:bd897a001012 1600
wim 26:bd897a001012 1601 // write the new data to the portexpander
wim 26:bd897a001012 1602 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1603 #else
wim 26:bd897a001012 1604 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1605
wim 22:35742ec80c24 1606 // write the new data to the I2C portexpander
wim 22:35742ec80c24 1607 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1608 #endif
wim 21:9eb628d9e164 1609 }
wim 21:9eb628d9e164 1610
wim 21:9eb628d9e164 1611 // Set RS pin
wim 21:9eb628d9e164 1612 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1613 void TextLCD_I2C::_setRS(bool value) {
wim 21:9eb628d9e164 1614
wim 26:bd897a001012 1615 if (value) {
wim 22:35742ec80c24 1616 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 26:bd897a001012 1617 }
wim 26:bd897a001012 1618 else {
wim 22:35742ec80c24 1619 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 26:bd897a001012 1620 }
wim 26:bd897a001012 1621
wim 26:bd897a001012 1622 #if (MCP23008==1)
wim 26:bd897a001012 1623 // MCP23008 portexpander
wim 26:bd897a001012 1624
wim 26:bd897a001012 1625 // write the new data to the portexpander
wim 26:bd897a001012 1626 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1627 #else
wim 26:bd897a001012 1628 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1629
wim 22:35742ec80c24 1630 // write the new data to the I2C portexpander
wim 22:35742ec80c24 1631 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 30:033048611c01 1632 #endif
wim 21:9eb628d9e164 1633 }
wim 21:9eb628d9e164 1634
wim 21:9eb628d9e164 1635 // Set BL pin
wim 21:9eb628d9e164 1636 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1637 void TextLCD_I2C::_setBL(bool value) {
wim 21:9eb628d9e164 1638
wim 26:bd897a001012 1639 if (value) {
wim 21:9eb628d9e164 1640 _lcd_bus |= D_LCD_BL; // Set BL bit
wim 26:bd897a001012 1641 }
wim 26:bd897a001012 1642 else {
wim 21:9eb628d9e164 1643 _lcd_bus &= ~D_LCD_BL; // Reset BL bit
wim 26:bd897a001012 1644 }
wim 26:bd897a001012 1645
wim 26:bd897a001012 1646 #if (MCP23008==1)
wim 26:bd897a001012 1647 // MCP23008 portexpander
wim 26:bd897a001012 1648
wim 26:bd897a001012 1649 // write the new data to the portexpander
wim 26:bd897a001012 1650 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1651 #else
wim 26:bd897a001012 1652 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1653
wim 21:9eb628d9e164 1654 // write the new data to the I2C portexpander
wim 21:9eb628d9e164 1655 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 30:033048611c01 1656 #endif
wim 21:9eb628d9e164 1657 }
wim 21:9eb628d9e164 1658
wim 21:9eb628d9e164 1659
wim 21:9eb628d9e164 1660 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1661 // Used for mbed pins, I2C bus expander or SPI shifregister
wim 21:9eb628d9e164 1662 void TextLCD_I2C::_setData(int value) {
wim 21:9eb628d9e164 1663 int data;
wim 22:35742ec80c24 1664
wim 22:35742ec80c24 1665 // Set bit by bit to support any mapping of expander portpins to LCD pins
wim 21:9eb628d9e164 1666
wim 22:35742ec80c24 1667 data = value & 0x0F;
wim 26:bd897a001012 1668 if (data & 0x01){
wim 22:35742ec80c24 1669 _lcd_bus |= D_LCD_D4; // Set Databit
wim 26:bd897a001012 1670 }
wim 26:bd897a001012 1671 else {
wim 26:bd897a001012 1672 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 26:bd897a001012 1673 }
wim 21:9eb628d9e164 1674
wim 26:bd897a001012 1675 if (data & 0x02){
wim 22:35742ec80c24 1676 _lcd_bus |= D_LCD_D5; // Set Databit
wim 26:bd897a001012 1677 }
wim 26:bd897a001012 1678 else {
wim 26:bd897a001012 1679 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 26:bd897a001012 1680 }
wim 21:9eb628d9e164 1681
wim 26:bd897a001012 1682 if (data & 0x04) {
wim 22:35742ec80c24 1683 _lcd_bus |= D_LCD_D6; // Set Databit
wim 26:bd897a001012 1684 }
wim 26:bd897a001012 1685 else {
wim 26:bd897a001012 1686 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 26:bd897a001012 1687 }
wim 21:9eb628d9e164 1688
wim 26:bd897a001012 1689 if (data & 0x08) {
wim 22:35742ec80c24 1690 _lcd_bus |= D_LCD_D7; // Set Databit
wim 26:bd897a001012 1691 }
wim 26:bd897a001012 1692 else {
wim 26:bd897a001012 1693 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 26:bd897a001012 1694 }
wim 21:9eb628d9e164 1695
wim 26:bd897a001012 1696 #if (MCP23008==1)
wim 26:bd897a001012 1697 // MCP23008 portexpander
wim 26:bd897a001012 1698
wim 26:bd897a001012 1699 // write the new data to the portexpander
wim 26:bd897a001012 1700 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1701 #else
wim 26:bd897a001012 1702 // PCF8574 of PCF8574A portexpander
wim 26:bd897a001012 1703
wim 22:35742ec80c24 1704 // write the new data to the I2C portexpander
wim 26:bd897a001012 1705 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1706 #endif
wim 22:35742ec80c24 1707
wim 22:35742ec80c24 1708 }
wim 21:9eb628d9e164 1709
wim 26:bd897a001012 1710 // Write data to MCP23008 I2C portexpander
wim 26:bd897a001012 1711 void TextLCD_I2C::_write_register (int reg, int value) {
wim 26:bd897a001012 1712 char data[] = {reg, value};
wim 26:bd897a001012 1713
wim 30:033048611c01 1714 _i2c->write(_slaveAddress, data, 2);
wim 26:bd897a001012 1715 }
wim 26:bd897a001012 1716
wim 23:d47f226efb24 1717 //---------- End TextLCD_I2C ------------
wim 21:9eb628d9e164 1718
wim 21:9eb628d9e164 1719
wim 28:30fa94f7341c 1720 //--------- Start TextLCD_I2C_N ---------
wim 28:30fa94f7341c 1721
wim 28:30fa94f7341c 1722 /** Create a TextLCD interface using a controller with native I2C interface
wim 28:30fa94f7341c 1723 *
wim 28:30fa94f7341c 1724 * @param i2c I2C Bus
wim 28:30fa94f7341c 1725 * @param deviceAddress I2C slave address (default = 0x7C)
wim 28:30fa94f7341c 1726 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 28:30fa94f7341c 1727 * @param bl Backlight control line (optional, default = NC)
wim 28:30fa94f7341c 1728 * @param ctrl LCD controller (default = ST7032_3V3)
wim 28:30fa94f7341c 1729 */
wim 28:30fa94f7341c 1730 TextLCD_I2C_N::TextLCD_I2C_N(I2C *i2c, char deviceAddress, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 28:30fa94f7341c 1731 TextLCD_Base(type, ctrl),
wim 28:30fa94f7341c 1732 _i2c(i2c){
wim 30:033048611c01 1733
wim 28:30fa94f7341c 1734 _slaveAddress = deviceAddress & 0xFE;
wim 28:30fa94f7341c 1735
wim 28:30fa94f7341c 1736 // Setup the I2C bus
wim 29:a3663151aa65 1737 // The max bitrate for ST7032i is 400kbit, lets stick to default here
wim 29:a3663151aa65 1738 _i2c->frequency(100000);
wim 29:a3663151aa65 1739 // _i2c->frequency(50000);
wim 30:033048611c01 1740
wim 28:30fa94f7341c 1741 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 28:30fa94f7341c 1742 if (bl != NC) {
wim 28:30fa94f7341c 1743 _bl = new DigitalOut(bl); //Construct new pin
wim 28:30fa94f7341c 1744 _bl->write(0); //Deactivate
wim 28:30fa94f7341c 1745 }
wim 28:30fa94f7341c 1746 else {
wim 28:30fa94f7341c 1747 // No Hardware Backlight pin
wim 28:30fa94f7341c 1748 _bl = NULL; //Construct dummy pin
wim 28:30fa94f7341c 1749 }
wim 28:30fa94f7341c 1750
wim 30:033048611c01 1751 #if(0)
wim 30:033048611c01 1752 //Sanity check
wim 30:033048611c01 1753 switch (_ctrl) {
wim 30:033048611c01 1754 case ST7032_3V3:
wim 30:033048611c01 1755 case ST7032_5V:
wim 30:033048611c01 1756 case PCF21XX_3V3:
wim 30:033048611c01 1757 // case PCF21XX_5V:
wim 30:033048611c01 1758 _init();
wim 30:033048611c01 1759 break;
wim 30:033048611c01 1760
wim 30:033048611c01 1761 default:
wim 30:033048611c01 1762 error("Error: LCD Controller type does not support native I2C interface\n\r");
wim 30:033048611c01 1763 }
wim 30:033048611c01 1764 #endif
wim 30:033048611c01 1765
wim 30:033048611c01 1766 //Sanity check
wim 30:033048611c01 1767 if (_ctrl & LCD_C_I2C) {
wim 30:033048611c01 1768 _init();
wim 30:033048611c01 1769 }
wim 30:033048611c01 1770 else {
wim 30:033048611c01 1771 error("Error: LCD Controller type does not support native I2C interface\n\r");
wim 30:033048611c01 1772 }
wim 30:033048611c01 1773
wim 28:30fa94f7341c 1774 }
wim 28:30fa94f7341c 1775
wim 28:30fa94f7341c 1776 TextLCD_I2C_N::~TextLCD_I2C_N() {
wim 28:30fa94f7341c 1777 if (_bl != NULL) {delete _bl;} // BL pin
wim 28:30fa94f7341c 1778 }
wim 28:30fa94f7341c 1779
wim 28:30fa94f7341c 1780 // Not used in this mode
wim 28:30fa94f7341c 1781 void TextLCD_I2C_N::_setEnable(bool value) {
wim 28:30fa94f7341c 1782 }
wim 28:30fa94f7341c 1783
wim 28:30fa94f7341c 1784 // Set RS pin
wim 28:30fa94f7341c 1785 // Used for mbed pins, I2C bus expander or SPI shiftregister and native I2C or SPI
wim 28:30fa94f7341c 1786 void TextLCD_I2C_N::_setRS(bool value) {
wim 30:033048611c01 1787 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 1788 // Start Slaveaddress+RW b7 b6 b5 b4 b3 b2 b1 b0 b7...........b0 Stop
wim 30:033048611c01 1789 // Co RS RW 0 0 0 0 0 command or data
wim 30:033048611c01 1790 //
wim 30:033048611c01 1791 // C0=1 indicates that another controlbyte will follow after the next data or command byte
wim 30:033048611c01 1792 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 1793 // RW=0 means write to controller. RW=1 means that controller will be read from after the next command.
wim 30:033048611c01 1794 // Many native I2C controllers dont support this option and it is not used by this lib.
wim 30:033048611c01 1795 //
wim 30:033048611c01 1796
wim 28:30fa94f7341c 1797 if (value) {
wim 28:30fa94f7341c 1798 _controlbyte = 0x40; // Next byte is data, No more control bytes will follow
wim 28:30fa94f7341c 1799 }
wim 28:30fa94f7341c 1800 else {
wim 28:30fa94f7341c 1801 _controlbyte = 0x00; // Next byte is command, No more control bytes will follow
wim 28:30fa94f7341c 1802 }
wim 28:30fa94f7341c 1803 }
wim 28:30fa94f7341c 1804
wim 28:30fa94f7341c 1805 // Set BL pin
wim 28:30fa94f7341c 1806 void TextLCD_I2C_N::_setBL(bool value) {
wim 28:30fa94f7341c 1807 if (_bl) {
wim 28:30fa94f7341c 1808 _bl->write(value);
wim 28:30fa94f7341c 1809 }
wim 28:30fa94f7341c 1810 }
wim 29:a3663151aa65 1811
wim 29:a3663151aa65 1812 // Not used in this mode
wim 29:a3663151aa65 1813 void TextLCD_I2C_N::_setData(int value) {
wim 29:a3663151aa65 1814 }
wim 29:a3663151aa65 1815
wim 28:30fa94f7341c 1816 // Write a byte using I2C
wim 28:30fa94f7341c 1817 void TextLCD_I2C_N::_writeByte(int value) {
wim 30:033048611c01 1818 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 1819 // Start Slaveaddress+RW b7 b6 b5 b4 b3 b2 b1 b0 b7...........b0 Stop
wim 30:033048611c01 1820 // Co RS RW 0 0 0 0 0 command or data
wim 30:033048611c01 1821 //
wim 30:033048611c01 1822 // C0=1 indicates that another controlbyte will follow after the next data or command byte
wim 30:033048611c01 1823 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 1824 // RW=0 means write to controller. RW=1 means that controller will be read from after the next command.
wim 30:033048611c01 1825 // Many native I2C controllers dont support this option and it is not used by this lib.
wim 30:033048611c01 1826 //
wim 28:30fa94f7341c 1827 char data[] = {_controlbyte, value};
wim 28:30fa94f7341c 1828
wim 30:033048611c01 1829 _i2c->write(_slaveAddress, data, 2);
wim 28:30fa94f7341c 1830 }
wim 28:30fa94f7341c 1831
wim 28:30fa94f7341c 1832 //-------- End TextLCD_I2C_N ------------
wim 28:30fa94f7341c 1833
wim 28:30fa94f7341c 1834
wim 23:d47f226efb24 1835 //--------- Start TextLCD_SPI -----------
wim 21:9eb628d9e164 1836
wim 22:35742ec80c24 1837 /** Create a TextLCD interface using an SPI 74595 portexpander
wim 22:35742ec80c24 1838 *
wim 22:35742ec80c24 1839 * @param spi SPI Bus
wim 22:35742ec80c24 1840 * @param cs chip select pin (active low)
wim 22:35742ec80c24 1841 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 22:35742ec80c24 1842 * @param ctrl LCD controller (default = HD44780)
wim 22:35742ec80c24 1843 */
wim 21:9eb628d9e164 1844 TextLCD_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1845 TextLCD_Base(type, ctrl),
wim 21:9eb628d9e164 1846 _spi(spi),
wim 21:9eb628d9e164 1847 _cs(cs) {
wim 21:9eb628d9e164 1848
wim 21:9eb628d9e164 1849 // Setup the spi for 8 bit data, low steady state clock,
wim 21:9eb628d9e164 1850 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 21:9eb628d9e164 1851 _spi->format(8,0);
wim 21:9eb628d9e164 1852 _spi->frequency(500000);
wim 21:9eb628d9e164 1853 //_spi.frequency(1000000);
wim 21:9eb628d9e164 1854
wim 21:9eb628d9e164 1855 // Init the portexpander bus
wim 21:9eb628d9e164 1856 _lcd_bus = D_LCD_BUS_DEF;
wim 21:9eb628d9e164 1857
wim 21:9eb628d9e164 1858 // write the new data to the portexpander
wim 21:9eb628d9e164 1859 _setCS(false);
wim 21:9eb628d9e164 1860 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 1861 _setCS(true);
wim 30:033048611c01 1862
wim 30:033048611c01 1863 _init();
wim 21:9eb628d9e164 1864 }
wim 21:9eb628d9e164 1865
wim 21:9eb628d9e164 1866 // Set E pin (or E2 pin)
wim 21:9eb628d9e164 1867 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1868 void TextLCD_SPI::_setEnable(bool value) {
wim 21:9eb628d9e164 1869
wim 22:35742ec80c24 1870 if(_ctrl_idx==_LCDCtrl_0) {
wim 26:bd897a001012 1871 if (value) {
wim 22:35742ec80c24 1872 _lcd_bus |= D_LCD_E; // Set E bit
wim 26:bd897a001012 1873 }
wim 26:bd897a001012 1874 else {
wim 22:35742ec80c24 1875 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 26:bd897a001012 1876 }
wim 22:35742ec80c24 1877 }
wim 22:35742ec80c24 1878 else {
wim 26:bd897a001012 1879 if (value) {
wim 22:35742ec80c24 1880 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 26:bd897a001012 1881 }
wim 26:bd897a001012 1882 else {
wim 22:35742ec80c24 1883 _lcd_bus &= ~D_LCD_E2; // Reset E2 bit
wim 26:bd897a001012 1884 }
wim 22:35742ec80c24 1885 }
wim 21:9eb628d9e164 1886
wim 22:35742ec80c24 1887 // write the new data to the SPI portexpander
wim 22:35742ec80c24 1888 _setCS(false);
wim 22:35742ec80c24 1889 _spi->write(_lcd_bus);
wim 30:033048611c01 1890 _setCS(true);
wim 21:9eb628d9e164 1891 }
wim 21:9eb628d9e164 1892
wim 21:9eb628d9e164 1893 // Set RS pin
wim 21:9eb628d9e164 1894 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1895 void TextLCD_SPI::_setRS(bool value) {
wim 21:9eb628d9e164 1896
wim 22:35742ec80c24 1897 if (value) {
wim 21:9eb628d9e164 1898 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 22:35742ec80c24 1899 }
wim 22:35742ec80c24 1900 else {
wim 21:9eb628d9e164 1901 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 22:35742ec80c24 1902 }
wim 21:9eb628d9e164 1903
wim 21:9eb628d9e164 1904 // write the new data to the SPI portexpander
wim 21:9eb628d9e164 1905 _setCS(false);
wim 21:9eb628d9e164 1906 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 1907 _setCS(true);
wim 21:9eb628d9e164 1908 }
wim 21:9eb628d9e164 1909
wim 21:9eb628d9e164 1910 // Set BL pin
wim 21:9eb628d9e164 1911 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1912 void TextLCD_SPI::_setBL(bool value) {
wim 21:9eb628d9e164 1913
wim 22:35742ec80c24 1914 if (value) {
wim 21:9eb628d9e164 1915 _lcd_bus |= D_LCD_BL; // Set BL bit
wim 22:35742ec80c24 1916 }
wim 22:35742ec80c24 1917 else {
wim 21:9eb628d9e164 1918 _lcd_bus &= ~D_LCD_BL; // Reset BL bit
wim 22:35742ec80c24 1919 }
wim 21:9eb628d9e164 1920
wim 21:9eb628d9e164 1921 // write the new data to the SPI portexpander
wim 21:9eb628d9e164 1922 _setCS(false);
wim 21:9eb628d9e164 1923 _spi->write(_lcd_bus);
wim 30:033048611c01 1924 _setCS(true);
wim 21:9eb628d9e164 1925 }
wim 21:9eb628d9e164 1926
wim 21:9eb628d9e164 1927 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1928 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1929 void TextLCD_SPI::_setData(int value) {
wim 21:9eb628d9e164 1930 int data;
wim 21:9eb628d9e164 1931
wim 22:35742ec80c24 1932 // Set bit by bit to support any mapping of expander portpins to LCD pins
wim 22:35742ec80c24 1933
wim 22:35742ec80c24 1934 data = value & 0x0F;
wim 26:bd897a001012 1935 if (data & 0x01) {
wim 22:35742ec80c24 1936 _lcd_bus |= D_LCD_D4; // Set Databit
wim 26:bd897a001012 1937 }
wim 26:bd897a001012 1938 else {
wim 22:35742ec80c24 1939 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 26:bd897a001012 1940 }
wim 26:bd897a001012 1941
wim 26:bd897a001012 1942 if (data & 0x02) {
wim 22:35742ec80c24 1943 _lcd_bus |= D_LCD_D5; // Set Databit
wim 26:bd897a001012 1944 }
wim 26:bd897a001012 1945 else {
wim 22:35742ec80c24 1946 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 26:bd897a001012 1947 }
wim 26:bd897a001012 1948
wim 26:bd897a001012 1949 if (data & 0x04) {
wim 22:35742ec80c24 1950 _lcd_bus |= D_LCD_D6; // Set Databit
wim 26:bd897a001012 1951 }
wim 26:bd897a001012 1952 else {
wim 22:35742ec80c24 1953 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 26:bd897a001012 1954 }
wim 26:bd897a001012 1955
wim 26:bd897a001012 1956 if (data & 0x08) {
wim 22:35742ec80c24 1957 _lcd_bus |= D_LCD_D7; // Set Databit
wim 26:bd897a001012 1958 }
wim 26:bd897a001012 1959 else {
wim 26:bd897a001012 1960 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 26:bd897a001012 1961 }
wim 21:9eb628d9e164 1962
wim 22:35742ec80c24 1963 // write the new data to the SPI portexpander
wim 22:35742ec80c24 1964 _setCS(false);
wim 22:35742ec80c24 1965 _spi->write(_lcd_bus);
wim 30:033048611c01 1966 _setCS(true);
wim 21:9eb628d9e164 1967 }
wim 21:9eb628d9e164 1968
wim 21:9eb628d9e164 1969 // Set CS line.
wim 21:9eb628d9e164 1970 // Only used for SPI bus
wim 21:9eb628d9e164 1971 void TextLCD_SPI::_setCS(bool value) {
wim 21:9eb628d9e164 1972
wim 21:9eb628d9e164 1973 if (value) {
wim 21:9eb628d9e164 1974 _cs = 1; // Set CS pin
wim 21:9eb628d9e164 1975 }
wim 22:35742ec80c24 1976 else {
wim 21:9eb628d9e164 1977 _cs = 0; // Reset CS pin
wim 22:35742ec80c24 1978 }
wim 21:9eb628d9e164 1979 }
wim 21:9eb628d9e164 1980
wim 23:d47f226efb24 1981 //---------- End TextLCD_SPI ------------
wim 22:35742ec80c24 1982
wim 22:35742ec80c24 1983
wim 25:6162b31128c9 1984 //--------- Start TextLCD_SPI_N ---------
Sissors 24:fb3399713710 1985
wim 30:033048611c01 1986 /** Create a TextLCD interface using a controller with a native SPI4 interface
Sissors 24:fb3399713710 1987 *
Sissors 24:fb3399713710 1988 * @param spi SPI Bus
Sissors 24:fb3399713710 1989 * @param cs chip select pin (active low)
wim 25:6162b31128c9 1990 * @param rs Instruction/data control line
Sissors 24:fb3399713710 1991 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 25:6162b31128c9 1992 * @param bl Backlight control line (optional, default = NC)
wim 26:bd897a001012 1993 * @param ctrl LCD controller (default = ST7032_3V3)
wim 25:6162b31128c9 1994 */
wim 25:6162b31128c9 1995 TextLCD_SPI_N::TextLCD_SPI_N(SPI *spi, PinName cs, PinName rs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 25:6162b31128c9 1996 TextLCD_Base(type, ctrl),
wim 25:6162b31128c9 1997 _spi(spi),
wim 25:6162b31128c9 1998 _cs(cs),
wim 25:6162b31128c9 1999 _rs(rs) {
Sissors 24:fb3399713710 2000
Sissors 24:fb3399713710 2001 // Setup the spi for 8 bit data, low steady state clock,
Sissors 24:fb3399713710 2002 // rising edge capture, with a 500KHz or 1MHz clock rate
Sissors 24:fb3399713710 2003 _spi->format(8,0);
Sissors 24:fb3399713710 2004 _spi->frequency(1000000);
Sissors 24:fb3399713710 2005
Sissors 24:fb3399713710 2006 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
Sissors 24:fb3399713710 2007 if (bl != NC) {
Sissors 24:fb3399713710 2008 _bl = new DigitalOut(bl); //Construct new pin
Sissors 24:fb3399713710 2009 _bl->write(0); //Deactivate
Sissors 24:fb3399713710 2010 }
Sissors 24:fb3399713710 2011 else {
Sissors 24:fb3399713710 2012 // No Hardware Backlight pin
Sissors 24:fb3399713710 2013 _bl = NULL; //Construct dummy pin
Sissors 24:fb3399713710 2014 }
wim 30:033048611c01 2015
wim 30:033048611c01 2016 #if(0)
wim 30:033048611c01 2017 //Sanity check
wim 30:033048611c01 2018 switch (_ctrl) {
wim 30:033048611c01 2019 case ST7032_3V3:
wim 30:033048611c01 2020 case ST7032_5V:
wim 30:033048611c01 2021 case WS0010:
wim 30:033048611c01 2022 _init();
wim 30:033048611c01 2023 break;
wim 30:033048611c01 2024
wim 30:033048611c01 2025 default:
wim 30:033048611c01 2026 error("Error: LCD Controller type does not support native SPI4 interface\n\r");
wim 30:033048611c01 2027 }
wim 30:033048611c01 2028 #endif
wim 30:033048611c01 2029
wim 30:033048611c01 2030 //Sanity check
wim 30:033048611c01 2031 if (_ctrl & LCD_C_SPI4) {
wim 30:033048611c01 2032 _init();
wim 30:033048611c01 2033 }
wim 30:033048611c01 2034 else {
wim 30:033048611c01 2035 error("Error: LCD Controller type does not support native SPI4 interface\n\r");
wim 30:033048611c01 2036 }
Sissors 24:fb3399713710 2037 }
Sissors 24:fb3399713710 2038
wim 25:6162b31128c9 2039 TextLCD_SPI_N::~TextLCD_SPI_N() {
Sissors 24:fb3399713710 2040 if (_bl != NULL) {delete _bl;} // BL pin
Sissors 24:fb3399713710 2041 }
Sissors 24:fb3399713710 2042
Sissors 24:fb3399713710 2043 // Not used in this mode
wim 25:6162b31128c9 2044 void TextLCD_SPI_N::_setEnable(bool value) {
Sissors 24:fb3399713710 2045 }
Sissors 24:fb3399713710 2046
Sissors 24:fb3399713710 2047 // Set RS pin
Sissors 24:fb3399713710 2048 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 25:6162b31128c9 2049 void TextLCD_SPI_N::_setRS(bool value) {
Sissors 24:fb3399713710 2050 _rs = value;
Sissors 24:fb3399713710 2051 }
Sissors 24:fb3399713710 2052
Sissors 24:fb3399713710 2053 // Set BL pin
wim 25:6162b31128c9 2054 void TextLCD_SPI_N::_setBL(bool value) {
wim 26:bd897a001012 2055 if (_bl) {
Sissors 24:fb3399713710 2056 _bl->write(value);
wim 26:bd897a001012 2057 }
Sissors 24:fb3399713710 2058 }
Sissors 24:fb3399713710 2059
wim 29:a3663151aa65 2060 // Not used in this mode
wim 29:a3663151aa65 2061 void TextLCD_SPI_N::_setData(int value) {
wim 29:a3663151aa65 2062 }
wim 29:a3663151aa65 2063
Sissors 24:fb3399713710 2064 // Write a byte using SPI
wim 25:6162b31128c9 2065 void TextLCD_SPI_N::_writeByte(int value) {
Sissors 24:fb3399713710 2066 _cs = 0;
Sissors 24:fb3399713710 2067 wait_us(1);
Sissors 24:fb3399713710 2068 _spi->write(value);
Sissors 24:fb3399713710 2069 wait_us(1);
Sissors 24:fb3399713710 2070 _cs = 1;
Sissors 24:fb3399713710 2071 }
wim 30:033048611c01 2072
wim 25:6162b31128c9 2073 //-------- End TextLCD_SPI_N ------------
wim 21:9eb628d9e164 2074
wim 21:9eb628d9e164 2075
wim 21:9eb628d9e164 2076
wim 30:033048611c01 2077 #if(0)
wim 30:033048611c01 2078 //Code checked out on logic analyser. Not yet tested on hardware..
wim 30:033048611c01 2079
wim 30:033048611c01 2080 //-------- Start TextLCD_SPI_N_3_9 --------
wim 30:033048611c01 2081
wim 30:033048611c01 2082 /** Create a TextLCD interface using a controller with a native SPI3 9 bits interface
wim 30:033048611c01 2083 *
wim 30:033048611c01 2084 * @param spi SPI Bus
wim 30:033048611c01 2085 * @param cs chip select pin (active low)
wim 30:033048611c01 2086 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 30:033048611c01 2087 * @param bl Backlight control line (optional, default = NC)
wim 30:033048611c01 2088 * @param ctrl LCD controller (default = AIP31068)
wim 30:033048611c01 2089 */
wim 30:033048611c01 2090 TextLCD_SPI_N_3_9::TextLCD_SPI_N_3_9(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 30:033048611c01 2091 TextLCD_Base(type, ctrl),
wim 30:033048611c01 2092 _spi(spi),
wim 30:033048611c01 2093 _cs(cs) {
wim 30:033048611c01 2094
wim 30:033048611c01 2095 // Setup the spi for 9 bit data, low steady state clock,
wim 30:033048611c01 2096 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 30:033048611c01 2097 _spi->format(9,0);
wim 30:033048611c01 2098 _spi->frequency(1000000);
wim 30:033048611c01 2099
wim 30:033048611c01 2100 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 30:033048611c01 2101 if (bl != NC) {
wim 30:033048611c01 2102 _bl = new DigitalOut(bl); //Construct new pin
wim 30:033048611c01 2103 _bl->write(0); //Deactivate
wim 30:033048611c01 2104 }
wim 30:033048611c01 2105 else {
wim 30:033048611c01 2106 // No Hardware Backlight pin
wim 30:033048611c01 2107 _bl = NULL; //Construct dummy pin
wim 30:033048611c01 2108 }
wim 30:033048611c01 2109
wim 30:033048611c01 2110 //Sanity check
wim 30:033048611c01 2111 if (_ctrl & LCD_C_SPI3_9) {
wim 30:033048611c01 2112 _init();
wim 30:033048611c01 2113 }
wim 30:033048611c01 2114 else {
wim 30:033048611c01 2115 error("Error: LCD Controller type does not support native SPI3 9 bits interface\n\r");
wim 30:033048611c01 2116 }
wim 30:033048611c01 2117 }
wim 30:033048611c01 2118
wim 30:033048611c01 2119 TextLCD_SPI_N_3_9::~TextLCD_SPI_N_3_9() {
wim 30:033048611c01 2120 if (_bl != NULL) {delete _bl;} // BL pin
wim 30:033048611c01 2121 }
wim 30:033048611c01 2122
wim 30:033048611c01 2123 // Not used in this mode
wim 30:033048611c01 2124 void TextLCD_SPI_N_3_9::_setEnable(bool value) {
wim 30:033048611c01 2125 }
wim 30:033048611c01 2126
wim 30:033048611c01 2127 // Set RS pin
wim 30:033048611c01 2128 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 30:033048611c01 2129 void TextLCD_SPI_N_3_9::_setRS(bool value) {
wim 30:033048611c01 2130 // The controlbits define the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 2131 // b8 b7...........b0
wim 30:033048611c01 2132 // RS command or data
wim 30:033048611c01 2133 //
wim 30:033048611c01 2134 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 2135 //
wim 30:033048611c01 2136
wim 30:033048611c01 2137 if (value) {
wim 30:033048611c01 2138 _controlbyte = 0x01; // Next byte is data
wim 30:033048611c01 2139 }
wim 30:033048611c01 2140 else {
wim 30:033048611c01 2141 _controlbyte = 0x00; // Next byte is command
wim 30:033048611c01 2142 }
wim 30:033048611c01 2143
wim 30:033048611c01 2144 }
wim 30:033048611c01 2145
wim 30:033048611c01 2146 // Set BL pin
wim 30:033048611c01 2147 void TextLCD_SPI_N_3_9::_setBL(bool value) {
wim 30:033048611c01 2148 if (_bl) {
wim 30:033048611c01 2149 _bl->write(value);
wim 30:033048611c01 2150 }
wim 30:033048611c01 2151 }
wim 30:033048611c01 2152
wim 30:033048611c01 2153 // Not used in this mode
wim 30:033048611c01 2154 void TextLCD_SPI_N_3_9::_setData(int value) {
wim 30:033048611c01 2155 }
wim 30:033048611c01 2156
wim 30:033048611c01 2157 // Write a byte using SPI3 9 bits mode
wim 30:033048611c01 2158 void TextLCD_SPI_N_3_9::_writeByte(int value) {
wim 30:033048611c01 2159 _cs = 0;
wim 30:033048611c01 2160 wait_us(1);
wim 30:033048611c01 2161 _spi->write( (_controlbyte << 8) | (value & 0xFF));
wim 30:033048611c01 2162 wait_us(1);
wim 30:033048611c01 2163 _cs = 1;
wim 30:033048611c01 2164 }
wim 30:033048611c01 2165
wim 30:033048611c01 2166 //------- End TextLCD_SPI_N_3_9 -----------
wim 30:033048611c01 2167 #endif
wim 21:9eb628d9e164 2168
wim 21:9eb628d9e164 2169
wim 30:033048611c01 2170 #if(0)
wim 30:033048611c01 2171 //Code checked out on logic analyser. Not yet tested on hardware..
wim 30:033048611c01 2172
wim 30:033048611c01 2173 //------- Start TextLCD_SPI_N_3_10 --------
wim 30:033048611c01 2174
wim 30:033048611c01 2175 /** Create a TextLCD interface using a controller with a native SPI3 10 bits interface
wim 30:033048611c01 2176 *
wim 30:033048611c01 2177 * @param spi SPI Bus
wim 30:033048611c01 2178 * @param cs chip select pin (active low)
wim 30:033048611c01 2179 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 30:033048611c01 2180 * @param bl Backlight control line (optional, default = NC)
wim 30:033048611c01 2181 * @param ctrl LCD controller (default = AIP31068)
wim 30:033048611c01 2182 */
wim 30:033048611c01 2183 TextLCD_SPI_N_3_10::TextLCD_SPI_N_3_10(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 30:033048611c01 2184 TextLCD_Base(type, ctrl),
wim 30:033048611c01 2185 _spi(spi),
wim 30:033048611c01 2186 _cs(cs) {
wim 30:033048611c01 2187
wim 30:033048611c01 2188 // Setup the spi for 10 bit data, low steady state clock,
wim 30:033048611c01 2189 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 30:033048611c01 2190 _spi->format(10,0);
wim 30:033048611c01 2191 _spi->frequency(1000000);
wim 30:033048611c01 2192
wim 30:033048611c01 2193 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 30:033048611c01 2194 if (bl != NC) {
wim 30:033048611c01 2195 _bl = new DigitalOut(bl); //Construct new pin
wim 30:033048611c01 2196 _bl->write(0); //Deactivate
wim 30:033048611c01 2197 }
wim 30:033048611c01 2198 else {
wim 30:033048611c01 2199 // No Hardware Backlight pin
wim 30:033048611c01 2200 _bl = NULL; //Construct dummy pin
wim 30:033048611c01 2201 }
wim 30:033048611c01 2202
wim 30:033048611c01 2203 //Sanity check
wim 30:033048611c01 2204 if (_ctrl & LCD_C_SPI3_10) {
wim 30:033048611c01 2205 _init();
wim 30:033048611c01 2206 }
wim 30:033048611c01 2207 else {
wim 30:033048611c01 2208 error("Error: LCD Controller type does not support native SPI3 10 bits interface\n\r");
wim 30:033048611c01 2209 }
wim 30:033048611c01 2210 }
wim 30:033048611c01 2211
wim 30:033048611c01 2212 TextLCD_SPI_N_3_10::~TextLCD_SPI_N_3_10() {
wim 30:033048611c01 2213 if (_bl != NULL) {delete _bl;} // BL pin
wim 30:033048611c01 2214 }
wim 30:033048611c01 2215
wim 30:033048611c01 2216 // Not used in this mode
wim 30:033048611c01 2217 void TextLCD_SPI_N_3_10::_setEnable(bool value) {
wim 30:033048611c01 2218 }
wim 30:033048611c01 2219
wim 30:033048611c01 2220 // Set RS pin
wim 30:033048611c01 2221 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 30:033048611c01 2222 void TextLCD_SPI_N_3_10::_setRS(bool value) {
wim 30:033048611c01 2223 // The controlbits define the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 2224 // b9 b8 b7...........b0
wim 30:033048611c01 2225 // RS RW command or data
wim 30:033048611c01 2226 //
wim 30:033048611c01 2227 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 2228 // RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib)
wim 30:033048611c01 2229 //
wim 30:033048611c01 2230
wim 30:033048611c01 2231 if (value) {
wim 30:033048611c01 2232 _controlbyte = 0x02; // Next byte is data
wim 30:033048611c01 2233 }
wim 30:033048611c01 2234 else {
wim 30:033048611c01 2235 _controlbyte = 0x00; // Next byte is command
wim 30:033048611c01 2236 }
wim 30:033048611c01 2237
wim 30:033048611c01 2238 }
wim 30:033048611c01 2239
wim 30:033048611c01 2240 // Set BL pin
wim 30:033048611c01 2241 void TextLCD_SPI_N_3_10::_setBL(bool value) {
wim 30:033048611c01 2242 if (_bl) {
wim 30:033048611c01 2243 _bl->write(value);
wim 30:033048611c01 2244 }
wim 30:033048611c01 2245 }
wim 30:033048611c01 2246
wim 30:033048611c01 2247 // Not used in this mode
wim 30:033048611c01 2248 void TextLCD_SPI_N_3_10::_setData(int value) {
wim 30:033048611c01 2249 }
wim 30:033048611c01 2250
wim 30:033048611c01 2251 // Write a byte using SPI3 10 bits mode
wim 30:033048611c01 2252 void TextLCD_SPI_N_3_10::_writeByte(int value) {
wim 30:033048611c01 2253 _cs = 0;
wim 30:033048611c01 2254 wait_us(1);
wim 30:033048611c01 2255 _spi->write( (_controlbyte << 8) | (value & 0xFF));
wim 30:033048611c01 2256 wait_us(1);
wim 30:033048611c01 2257 _cs = 1;
wim 30:033048611c01 2258 }
wim 30:033048611c01 2259
wim 30:033048611c01 2260 //------- End TextLCD_SPI_N_3_10 ----------
wim 30:033048611c01 2261 #endif